题目描述
小 AA 和小 BB 在下五子棋。
五子棋是在一个由网格构成的棋盘内进行的。
网格有 1515 行 1515 列,共有 225225 个交叉点。
小 AA 先手执黑棋,小 BB 后手执白棋。
两人轮流下棋,每次下棋都将一个自己的棋子放在棋盘上一个空白的交叉点上。
然而,由于小 AA 和小 BB 都不知道五子棋的胜利条件,所以即使有一方已经胜利了,他们仍然会继续下棋。
现在想请你帮忙分析一下,所下的棋局是在第几步结束的。
当然,也有可能他们最终仍然没有分出胜负,这时请判定他们平局。
五子棋的胜利条件是这样的:当同一行或同一列或同一斜线(即与网格线成 45°45° 角的直线)上连续的五个或五个以上交叉点放有同色棋子的时候,立即判定使用该颜色棋子的玩家获得胜利,游戏结束。
输入格式
第一行输入一个正整数 nn,表示双方总共下了多少步棋。
接下来 nn 行,每行两个正整数。其中,第 ii 行的两个数 x,yx,y 表示第 ii 步的棋子下在了第 xx 条横线和第 yy 条竖线的交叉点上。若 ii 为奇数,则这个棋子是黑棋,否则是白棋。
输出格式
若没有人获得胜利,你需要输出“Tie”“Tie”(不含引号)。
否则,若小 AA 获胜,输出 “A”“A”(不含引号),若小 BB 获胜,输出 “B”“B”(不含引号);并输出一个正整数 ww 表示第 ww 步下完后游戏应当结束,字母与整数间用一个空格隔开。
数据范围
对于 20%20% 的数据,游戏结果是平局。
对于 30%30% 的数据,游戏在最后一手结束。
对于 100%100% 的数据,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下的棋子设为1,B的设为2
然后每下一步就检查是不是有能够连成5个或以上的
代码
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 30;
int g[N][N];
int n;
//
bool check(int x, int y, int t)
{
// 上下
int tx = x;
int cnt = 0;
while(tx >= 1 && g[tx][y] == t) cnt++, tx--;
tx = x;
cnt--;
while(tx <= 15 && g[tx][y] == t) cnt++, tx++;
if(cnt >= 5) return true;
// ---左右
int ty = y;
cnt = 0;
while(ty >= 1 && g[x][ty] == t) cnt++, ty--;
ty = y;
cnt--;
while(ty <= 15 && g[x][ty] == t) cnt++, ty++;
if(cnt >= 5) return true;
//正对角线
tx = x, ty = y, cnt = 0;
while(tx >= 1 && ty >= 1 && g[tx][ty] == t) tx--, ty--, cnt++;
tx = x, ty = y;
cnt--;
while(tx <= 15 && ty <= 15 && g[tx][ty] == t) tx++, ty++, cnt++;
if(cnt >= 5) return true;
// 副对角线
tx = x, ty = y, cnt = 0;
while(tx >= 1 && ty <= 15 && g[tx][ty] == t) tx--, ty++, cnt++;
tx = x, ty = y;
cnt--;
while(tx <= 15 && ty >= 1 && g[tx][ty] == t) tx++, ty--, cnt++;
if(cnt >= 5) return true;
return false;
}
int main()
{
bool flag = false;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
int x, y, t;
scanf("%d%d", &x, &y);
if(i%2) t = 1;
else t = 2;
g[x][y] = t;
if(!flag && check(x, y, t))
{
flag = true;
if(t == 1) printf("A %d\n", i);
else printf("B %d\n", i);
}
}
if(!flag) printf("Tie\n");
return 0;
}