Codeforces Beta Round #3 C Tic-tac-toe

翻译

给你一个 3 3 棋盘,要你判断 A , B 哪个选手赢了,或者该谁下了,或者平局,或者棋盘不符合规则。

思路

我们通过分析可以确定(当然主要看代码无比详细的注释):

  • A 赢,且 B 不赢, A 的步数比 B 1 。就输出the first player won
  • B 赢,且 A 不赢,A跟B的步数一样。就输出thesecond player won
  • A 和B都不赢, A 的步数是 5 B 的步数是 4 . 就输出 draw
  • A 和B都不赢, A 的步数跟 B 的一样,该 A 走了。就输出first
  • A 和B都不赢, A 的步数比 B 1 ,该 B 走了。就输出thesecond player won
  • 剩下的不符合规则,输出 illegal

Code

#include <iostream>
using namespace std;

const int Maxn = 3;

char B[Maxn][Maxn];//棋盘 

int Calc(char c)
{
    int res = 0;//记录出现次数的 
    for (int i = 0; i < Maxn; i++)
       for (int j = 0; j < Maxn; j++)
          res += B[i][j] == c;//如果B[i][j]==c的值为真,res++;为假res+=0; 
    return res;
}

bool Win(char c)
{
     for (int i = 0; i < Maxn; i++) {
         int j;
         for (j = 0; j < Maxn; j++) if (B[i][j] != c) break; 
         if (j == Maxn) return true; 
         /*
         b[0][0]
   b[0][1]  X0X
        .0.
        .X.
   b[0][2]

      b[1][0]
   b[1][1]
   b[1][2]

   b[2][0]
   b[2][1]
   b[2][2]
   */ 
   //在上面可以看出 ,这是横寻找一个不是C的字符,要是某一行找不到就返回tuue 
     }
     for (int j = 0; j < Maxn; j++) {
         int i;
         for (i = 0; i < Maxn; i++) if (B[i][j] != c) break;
         if (i == Maxn) return true;
         /*
         j=0 i=0

   b[0][0] X0X
              .0.
              .X.
   b[1][0]
   b[2][0]

   b[0][1]
   b[1][1]
   b[2][1]

   b[0][2]
   b[1][2]
   b[2][2]

         */
        //在上面可以看出 ,这是竖着寻找一个不是C的字符,要是某一列找不到就返回tuue 
     }
     int i;
     for (i = 0; i < Maxn; i++) if (B[i][i] != c) break;//向右斜着找,要是找不到返回true 
     if (i == Maxn) return true;
     for (i = 0; i < Maxn; i++) if (B[i][Maxn-1-i] != c) break; //向左斜着找,要是找不到返回true 

  return i == Maxn;
  //这里因为必须有返回值,所以在i==Maxn的时候依旧返回true,只不过i!=Maxn需要返回false 
}
/*
造一个x赢的,看看是怎么判断胜负 

x0x
0x0
0xx


首先开始函数
横着找。。找x,第一行没有不是x的
第二行有不是x的
第三行同理
继续。。。
竖着找了,第一列,第二列,第三列都有不是x的
右斜找,哇都是X!返回true 
看来大家明白了 
*/
int main()
{
    for (int i = 0; i < Maxn; i++)
       for (int j = 0; j < Maxn; j++) cin >> B[i][j];//读入数据 
    int X = Calc('X'), O = Calc('0');//统计有几个X和0,注意0和O的区别来阅读 
    bool winX = Win('X'), winO = Win('0');//如Win函数 
    if (X < O || X > O + 1 || winX && X == O || winO && X == O+1) //不合法情况
 /*
 因为是X先下,所以X的次数不可比0的次数少
 因为X先下, 0紧跟着下,所以X出现的次数不会比0出现多超过1
 要是X数量等于0的数量,而此时存在三个X相连。这是不可能的,因为先手下子之后,X的数量必然多于0的数量,不可能相等。
 要是X的数量大于0的数量,而此时存在三个0相连。这是不可能的,因为后手下子之后X的数量和0的数量应当相等。 
 */ 
  cout << "illegal\n"; 
    else if (winX && winO) cout << "illegal\n";//如果双方都赢了(也不就是非法啊) 
    else if (winX) cout << "the first player won\n";//x获胜 
    else if (winO) cout << "the second player won\n";//0获胜 
    else if (X + O == Maxn*Maxn) cout << "draw\n";//当填满了也没出现获胜或非法,ok就平局. 
    else if (X == O) cout << "first\n";//相等情况,x必须比0多1,并且都没获胜,所以先手下 
    else if (X == O + 1) cout << "second\n";//要是X比O多1,并且都没获胜,那么后手下 
    else cout << "illegal\n";//无以上情况,当然非法 
    return 0;//完美结束 
}

猜你喜欢

转载自blog.csdn.net/qq_39984146/article/details/81840773
今日推荐