[CodeForces3C]Tic-tac-toe
阿新 • • 發佈:2018-06-17
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