题目链接:
http://poj.org/problem?id=2361
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1908
题目描述:
Tic Tac Toe是一个小孩玩的游戏,在一个3×3的棋盘中进行。游戏在两个玩家之间进行。其中一个玩家(用字符“X”表示)先走棋,在一个没有被占用的网格位置放置一个X,然后另一个玩家(用数字字符“0”表示),在一个没有被占用的网格中放置一个0。
这两个玩家交替地放置X和0,直到没有棋盘的网格都被占用了,或者某个玩家的棋子占据了整条线(水平、垂直或者对角线)。
游戏开始时棋盘是空的,用3行3列共9个字符“.”表示。如果X玩家走棋,则在相应位置上放置X;如果是0玩家走棋,则在相应位置上放置0。
你的任务是读入棋盘状态,问可不可能是一个有效的三子棋棋盘,也就是说是否存在一系列走棋,能到达该棋盘状态。
输入描述:
输入的第一行是整数N,表示测试数据的个数,接下来有4×N-1行,表示N个棋盘格局,每两个棋盘格局之间用空行隔开。
输出描述:
对每个棋盘格局,如果是一个有效的三子棋格局,则输出yes,否则输出no。
分析:
假设读入的棋盘格局中字符“X”和字符“0”的数目分别为xcount和ocount。(思考:能否将变量名定义成0count?)另外,如果棋盘中某行、某列、主对角线或次对角线都为某玩家的字符,则该玩家赢得了游戏。以下情形是不合法的棋盘格局:
1) ocount > xcount,因为玩家X总是先走棋;
2) xcount > ocount + 1,玩家X顶多比玩家0多走一步棋;
3) 玩家X和玩家0都赢得了游戏;
4) 玩家0赢得了游戏,但xcount不等于ocount;
5) 玩家X赢得了游戏,但xcount等于ocount。
注意以上第4和第5种情形,如果是玩家0赢得了游戏,则合法的情形是玩家0和玩家X走棋的步数一样;而如果是玩家X赢得了游戏,则合法的情形是玩家X走棋步数比和玩家0走棋步数多1步。
将棋盘格局读入到一个二维字符数组中,然后通过遍历该二维数组,统计字符“X”和字符“0”的数目,以及判断玩家X或玩家0是否赢得了游戏,再按照上述规则判断即可。
代码:
#include <iostream>
#include<cstdio>
using namespace std;
char str[4][4];
int win(char c)
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3 && str[i][j]==c;j++)
if(j==2) return 1;
for(int j=0;j<3 && str[j][i]==c;j++)
if(j==2) return 1;
}
for(int i=0;i<3 && str[i][i]==c;i++)
if(i==2) return 1;
for(int i=0;i<3 && str[i][2-i]==c;i++)
if(i==2) return 1;
return 0;
}
int main()
{
int n;
scanf("%d",&n);
getchar();
while(n--)
{
bool flag=true;
int ocount=0,xcount=0;
scanf(" %s %s %s", str[0], str[1], str[2] );
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
// cin>>str[i][j];
if(str[i][j]=='X')
xcount++;
if(str[i][j]=='O')
ocount++;
}
if(ocount>xcount || xcount>ocount+1)
flag=false;
if(win('X') && win('O'))
flag=false;
if(win('O') && ocount!=xcount)
flag=false;
if(win('X') && xcount==ocount)
flag=false;
if(flag)
printf("yes\n");
else
printf("no\n");
}
return 0;
}