POJ 2361/ZOJ 1908 Tic Tac Toe

题目链接:

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”的数目分别为xcountocount。(思考:能否将变量名定义成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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值