解题思路:由于X先走并且两个人轮流执子,所以当网格图无效的时候,存在下列5种情况:
(1)O的个数大于X
(2)X的个数至少比O大2
(3)O和X同时赢
(4)X赢,但是双方的棋子数一样
(5)O赢,但是双方棋子数不同
技巧:用一个标志位flag来判断是否合法,尤其注意掌握判断行、列、对角线的元素是否相同的方法,技巧性较强。
#include<stdio.h>
char plant[4][4];
int i,j;
//判断是否赢
int win(char c)
{
for(i=0;i<3;i++)
{ //判断一行是否相同
for(j=0;j<3 && plant[i][j]==c;j++)
if(j==2) return 1;
//判断一列是否相同
for(j=0;j<3 && plant[j][i]==c;j++)
if(j==2) return 1;
}
//判断主对角线是否相同
for(i=0;i<3 && plant[i][i]==c;i++)
if(i==2) return 1;
//判断次对角线是否相同
for(i=0;i<3 && plant[i][2-i]==c;i++)
if(i==2) return 1;
return 0;
}
int main()
{
int flag;//用来标注是否合法
int n,xcount,ocount;
while(scanf("%d",&n)!=EOF)
{
getchar();
while(n--)
{
xcount=0;
ocount=0;
for(i=0;i<3;i++) //输入网络
scanf("%s",plant[i]);
flag=1;
//计算X和O出现的次数,判断是否合法提供依据
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if(plant[i][j]=='X')
xcount++;
else if(plant[i][j]=='O')
ocount++;
}
}
//两个人同时赢
if(win('X') && win('O'))
flag=0;
//X赢了,但是双方棋子一样多
if(win('X') && xcount==ocount)
flag=0;
//O的个数大于X 或者X的数目比O大至少2个
if(ocount>xcount ||xcount-ocount>1)
flag=0;
//判断O赢,但是双方棋子不等
if(win('O') && ocount!=xcount)
flag=0;
//判断X赢,但是双方棋子个数相同
if(win('X') && ocount==xcount)
flag=0;
if(flag)
printf("yes\n");
else
printf("no\n");
}
}
return 0;
}