1. 程式人生 > >[CodeForces3C]Tic-tac-toe

[CodeForces3C]Tic-tac-toe

won IV 思路 怎麽 sin TE char S3 ||

Translate

一個 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;//完美結束 }

[CodeForces3C]Tic-tac-toe