【问题描述】
井字棋,是一种在3×3格子上进行的连珠游戏,和五子棋比较类似,由于棋盘一般不画边框,格线排成井字故得名。游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记井字策略。任意三个标记形成一条直线,则为获胜。
Alice和Bob考完了期末考试,并获得了100分的好成绩,正觉无聊,于是开始玩起了井字棋。
给出 n 个3×3的字符数组,用于表示 n 次对局最终的标记情况。
由于总是一个人先手会使得游戏趣味性降低,每一局的先手者并不是固定的。
具体给出一个长度为 n 的字符串s,s的第 i 个字符表示第 i 场对局的先手者是谁(0≤ i <n),‘A’表示Alice先手,‘B’表示Bob先手。
先手者执“1”棋子,后手者执“2”棋子,无棋子处用“0”表示。
请分别判断这个 n 次对局的获胜者。
题目数据保证所有的局面都是合法且可判断唯一获胜者的。
【输入形式】
输入的第一行包含一个正整数 n ( n ≤300),表示对局的次数。
输入的第二行包含一个字符串s,表示各对局的先手情况。
接下来3 * n 行,每行由一个长度为3的字符串组成,每3行共9个字符对应一个局面。
【输出形式】
输出共 n 行,每行输出A或B,表示每场对局的获胜者是谁。
【样例输入】
2 AB 120 112 201 222 101 010
【样例输出】
A A
【样例说明】
第一场对局中棋子1在正对角线上三个相连,而Alice先手,所以Alice获胜
第二场对局中棋子2在第一行上三个相连,而Bob先手,Alice后手,所以Alice获胜
【提示】
不必深究具体的下棋过程,只需判断最终的获胜棋子,再根据先后手情况给出答案即可。
代码(不使用容器):
#include <iostream>
#include <cstring>
using namespace std;
// 检查棋盘局面是否有获胜者
char checkWinner(char board[3][3]) {
// 检查每一行
for (int i = 0; i < 3; i++) {
if (board[i][0] != '0' && board[i][0] == board[i][1] && board[i][0] == board[i][2]) {
return board[i][0]; // 返回获胜者的棋子类型
}
}
// 检查每一列
for (int j = 0; j < 3; j++) {
if (board[0][j] != '0' && board[0][j] == board[1][j] && board[0][j] == board[2][j]) {
return board[0][j]; // 返回获胜者的棋子类型
}
}
// 检查两条对角线
if (board[0][0] != '0' && board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
return board[0][0]; // 返回获胜者的棋子类型
}
if (board[2][0] != '0' && board[2][0] == board[1][1] && board[2][0] == board[0][2]) {
return board[2][0]; // 返回获胜者的棋子类型
}
return ' '; // 没有获胜者,返回空格
}
int main() {
int n;
cin >> n;
char players[301];
cin >> players;
for (int i = 0; i < n; i++) {
char board[3][3];
for (int j = 0; j < 3; j++) {
cin >> board[j];
}
char winner = checkWinner(board);
if (winner == '1') {
cout << (players[i] == 'A' ? 'A' : 'B') << endl;
} else if (winner == '2') {
cout << (players[i] == 'A' ? 'B' : 'A') << endl;
} else {
cout << "No winner" << endl;
}
}
return 0;
}