1324. 五子棋

孤街浪徒 提交于 2020-02-28 00:02:47

小 A 和小 B 在下五子棋。

五子棋是在一个由网格构成的棋盘内进行的。

网格有 15行 15 列,共有 225 个交叉点。

小 A 先手执黑棋,小 B 后手执白棋。

两人轮流下棋,每次下棋都将一个自己的棋子放在棋盘上一个空白的交叉点上。

然而,由于小 A 和小 B 都不知道五子棋的胜利条件,所以即使有一方已经胜利了,他们仍然会继续下棋。

现在想请你帮忙分析一下,所下的棋局是在第几步结束的。

当然,也有可能他们最终仍然没有分出胜负,这时请判定他们平局。

五子棋的胜利条件是这样的:当同一行或同一列或同一斜线(即与网格线成 45° 角的直线)上连续的五个或五个以上交叉点放有同色棋子的时候,立即判定使用该颜色棋子的玩家获得胜利,游戏结束。

输入格式

第一行输入一个正整数 n,表示双方总共下了多少步棋。

接下来 n 行,每行两个正整数。其中,第 i行的两个数 x,y表示第 i步的棋子下在了第 x 条横线和第 y 条竖线的交叉点上。若 i 为奇数,则这个棋子是黑棋,否则是白棋。

输出格式

若没有人获得胜利,你需要输出“Tie(不含引号)。

否则,若小 A 获胜,输出 “A”(不含引号),若小 B 获胜,输出 “B”(不含引号);并输出一个正整数 w 表示第 w 步下完后游戏应当结束,字母与整数间用一个空格隔开。

数据范围

对于 20% 的数据,游戏结果是平局。
对于 30的数据,游戏在最后一手结束。
对于 100%1 的数据,0≤n≤225,1≤x,y≤150≤n≤225,1≤x,y≤15。

输入样例:

9
1 1
2 1
1 2
2 2
1 3
2 3
1 4
2 4
1 5

输出样例:

A 9

思路 : 用一个二维数组模拟棋盘, a[i][j] = 1 表示黑棋子 , a[i][j] = 2 表示白棋子 , a[i][j] = 0 为 没有下棋 。

每当下一个棋子(x,y) ,扫描棋盘是否出现 5 子连一起的情况 ,枚举 该枚棋子的4个方向的正反方向,计算出一个方向上

和该枚棋子颜色一样的个数 ,如果棋子个数 大于等于 5 ,则出现赢棋局面。

 按照左边图示方向进行枚举,如果枚举8个方向也可以,不过有点繁琐,直接 4个方向即可。

#include <iostream> 
#include <cstdio> 
#include <algorithm> 
#include <string> 
using namespace std ;
typedef long long LL  ; 
/* 

*/
const int MAX = 20 ; 
const int inf = 0x3f3f3f3f ;  
int n ; // 总共的棋子数量  
int a[MAX][MAX];
int dx[4] = {1,0,1,-1} ; 
int dy[4] = {0,1,1,1} ; 
bool success = false ; 
int state ; 
int scan(int x , int y) {
   
    // 对四个方向进行枚举 
    for(int i = 0 ;i<4 ; i++ ) {
        int l = 0 ; // 正方向的棋子数
        int r = 0 ; // 负方向的棋子数
        while(true) {
            int tx = x - dx[i] *(1+l) ; 
            int ty = y - dy[i] *(1+l) ;  
            if(tx <1 || tx >15 || ty<1 || ty >15) break ; // 出界
            if(a[tx][ty] !=a[x][y]) break ; // 没有相同的棋子了 
            l++ ; 
        }
        while(true ) {
            int tx = x + dx[i]*(r+1) ; 
            int ty = y + dy[i]*(r+1) ; 
            if(tx <1 || tx >15 || ty<1 || ty >15) break ; // 出界
            if(a[tx][ty] !=a[x][y]) break ; // 没有相同的棋子了 
            r++ ;
        }
        if(l+r >=4 ) {
            success = true ;  
            return 1 ;  // 出现五子
        }


    }
    
    return 0 ; 

} 
int main(){

    int step = 0 ; 
    cin >> n ; 
    for(int i = 1 ;i<=n ; i++ ) {
        int x ,y ; 
        cin >>x >>y ; 
        step++ ; 
        if(i&1) { // 黑棋子
            a[x][y] = 1 ;   
        }   
        else { // 白棋子
            a[x][y] = 2 ;
        }
        int check = scan(x,y)  ; 
        if(success) {
            if(i&1){
                state = 1 ; 
            }
            else {
                state = 2 ; 
            }
            step = i ; 
            break ; 
        }
        
        
    }

    if(state == 0 ) {
        cout<<"Tie"<<endl ;
    }
    else if(state == 1 ){
        cout<<"A "<<step <<endl ;
    }
    else {
        cout<<"B "<<step<<endl; 
    }


    
    return 0 ; 
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!