AC代码:
#include <stdio.h> void judge (char a[3][3]); int main() { int n,i; char qipan[3][3]; scanf("%d",&n); while (n--){ for (i=0;i<3;i++) scanf("%s",qipan[i]); judge(qipan); } return 0; } void judge (char a[3][3]) { int i,j,sum0=0,sumX=0,other=0,sum[8]={0},cntX=0,cnt0=0; //sum0记录“0”的个数,sumX记录“X”的个数 ,other则是记录“.”的个数 // sum[8]用来记录3行,3列,2对角线上元素的和 //cntX和cnt0记录有几行(列、对角线)全是“X”或“0" for (i=0;i<3;i++) for (j=0;j<3;j++){ if (a[i][j]=='0') sum0++; else if (a[i][j]=='X') sumX++; else other++; }//进行扫描累加 for (i=0;i<3;i++){ sum[i]=a[i][0]+a[i][1]+a[i][2];//每行求和 sum[i+3]=a[0][i]+a[1][i]+a[2][i];//每列求和 } sum[6]=a[0][0]+a[1][1]+a[2][2];//主对角线求和 sum[7]=a[0][2]+a[1][1]+a[2][0];//副对角线求和 for(i=0;i<8;i++){ if (sum[i]==3*'X') cntX++; if (sum[i]==3*'0') cnt0++; }//巧妙之处在于 用每行(列、对角线)元素之和与 3*'X'(3*'0')的值 来间接判断 是否连成三子! /* **************************************************************** 以下几种情况输入的棋盘判为非法(以下行泛指:行、列、对角线): 1、后手的个数多于先手 2、先手的个数多于后手一个以上 3、先手有2行以上都连成三子 或 后手有1行以上连成三子 这边可能有疑问就是为什么先手是2行以上,而不是1行以上就判为非法? 举个列子: X 0 0 0 X 0 X X X 显然先手是可以在合法的情况下有2行连成三子的 4、先手有1行连成三子,同时,后手也有1行连成三子 5、先手的个数与后手的个数相等,但先手已经连成了三子 6、先手的个数比后手多一个,但是后手已经连成了三子 ********************************************************************/ if(sum0>sumX || sumX-sum0>1 || cntX>2 || cnt0>1 || (cntX==1 && cnt0==1)||(sum0==sumX && cntX==1) || (sumX-sum0==1 && cnt0==1)) printf("illegal\n"); else{//在合法棋盘的情况下进行判断 if (cntX>0) printf("the first player won\n"); else if (cnt0>0) printf("the second player won\n"); else if (cntX==0 && cnt0==0 && other==0)//如果棋盘已经摆满(即other==0),但是没有一行连成三子,则平局 printf("draw\n"); else if (sum0==sumX) printf("first\n"); else printf("second\n"); } }