六形棋(chess)
该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
Description
【问题描述】
Jimmy 和 Chen 在下一种奇怪的棋,叫做六形棋。
棋盘由 N × N 个六边形格子构成,如下图所示:

当棋盘上的两个六边形格子有一条边重合的时候,我们称两个格子是互相连通的。将从上往下第 i 行、从左到右第 j 个格子称为 (i, j)。对于一个不在边界上的格子 (i, j),它和(i, j + 1),(i, j − 1),(i + 1, j),(i + 1, j − 1),(i − 1, j),(i − 1, j + 1) 这 6 个格子互相连通,而边界上的格子只与上述格子中未出界的格子互相连通。
六形棋的游戏规则如下:两人轮流下棋,Jimmy 先手,Jimmy 每次选一个空的格子下一个红色棋子,接下来 Chen 每次选一个空的格子下一个蓝色棋子,依次类推。如果最后Jimmy 将上下两条红色的边界用红色棋子连通了,那么 Jimmy 胜;相反,如果 Chen 将左右两条蓝色边界用蓝色棋子连通了,那么 Chen 胜。
接下来给出若干个六形棋的棋盘,请你判断每一局是 Jimmy 胜,还是 Chen 胜,还是目前未分出胜负(容易证明,不可能两人都达到获胜条件)。
【输入格式】
本题输入有多组测试数据。
第一行一个正整数 T,代表他们下了 T 盘棋。
每组数据的第一行为一个正整数 N,代表棋盘的大小。
每组数据的第 2 ∼ N + 1 行,每行 N 个 −1, 0, 1 中的整数,第 i + 1 行的第 j 个整数代表格子 (i, j) 的状态,如果为 −1 则该格子中为蓝色棋子,如果为 0 则该格子为空,如果为1 则该格子中为红色棋子。
【输出格式】
输出共 T 行,每行一个字符串,表示输入的棋盘对应的局面:如果 Jimmy 胜,则输出Jimmy;如果 Chen 胜,则输出 Chen;如果目前未分出胜负,则输出 yet。注意:Jimmy 和Chen 的首字母都需要大写。
【样例解释】
在第一个棋盘中,不存在将上下边界连通的红色棋子序列,也不存在将左右边界连通的
蓝色棋子序列,故目前未分出胜负。
在第二个棋盘中,上下两个边界由 (1, 3),(2, 3),(3, 3),(4, 3) 这些红色棋子连通了,所以
Jimmy 获胜了。
在第三个棋盘中,左右两个边界由 (3, 1),(2, 2),(1, 3),(1, 4) 这些蓝色棋子连通了,所以
Chen 获胜了。
【测试点约束】
对于 20% 的数据,保证 1 ≤ N ≤ 3。
对于另外 40% 的数据,保证给出的棋局已经分出胜负。
对于 100% 的数据,保证 1 ≤ T ≤ 10,1 ≤ N ≤ 100。
3
4
0 1 0 -1
0 -1 1 0
-1 -1 1 0
0 0 1 0
4
0 1 1 -1
0 -1 1 0
-1 -1 1 0
0 0 1 0
4
0 1 -1 -1
0 -1 1 1
-1 -1 1 0
0 0 1 0yet
Jimmy
Chen
Hint
#include <bits/stdc++.h>
using namespace std;
const int N=110;
int dx[6]={0,0,1,1,-1,-1};
int dy[6]={1,-1,0,-1,0,1};
int n,a[N][N],b[N][N];
void dfs(int x,int y)
{
b[x][y]=1;
for(int i=0;i<6;i++)
{
int xx=x+dx[i],yy=y+dy[i];
if(xx>=0 && xx<=n+1 && yy>=0 && yy<=n+1)
if(a[x][y]==a[xx][yy]&&b[xx][yy]==0)
dfs(xx,yy);
}
}
int main()
{
freopen("a.in","r",stdin);
int T;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
a[0][i]=1;
a[n+1][i]=1;
a[i][0]=-1;
a[i][n+1]=-1;
}
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);
memset(b,0,sizeof(b));
dfs(0,1);
if(b[n+1][1]!=0)
{
printf("Jimmy\n");
continue;
}
dfs(1,0);
if(b[1][n+1]!=0) printf("Chen\n");
else printf("yet\n");
}
return 0;
}
</p>