题目链接: [Tic-Tac-Toe]
大致题意:
横竖斜连成一行获胜,问Kim能不能在两步之内完成连线,如果可以输出Kim win,否则输出Cannot win
解题思路:
首先我们暴力枚举一个位子,使得这个位子就是Kim下的位子,然后check一下是否能够胜利,然后我们不枚举对方的走法,因为对方一定会阻止Kim,所以我们枚举Kim下一步走哪里会赢,Kim的下一步如果有两个位子以上的放置方案会赢
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int a[5][5];
int check(int kim)
{
if (a[0][0] == a[0][1] && a[0][1] == a[0][2] && a[0][0] == kim)return 1;
if (a[1][0] == a[1][1] && a[1][1] == a[1][2] && a[1][0] == kim)return 1;
if (a[2][0] == a[2][1] && a[2][1] == a[2][2] && a[2][0] == kim)return 1;
if (a[0][0] == a[1][1] && a[1][1] == a[2][2] && a[0][0] == kim)return 1;
if (a[0][2] == a[1][1] && a[1][1] == a[2][0] && a[0][2] == kim)return 1;
if (a[0][0] == a[1][0] && a[1][0] == a[2][0] && a[0][0] == kim)return 1;
if (a[0][1] == a[1][1] && a[1][1] == a[2][1] && a[0][1] == kim)return 1;
if (a[0][2] == a[1][2] && a[1][2] == a[2][2] && a[0][2] == kim)return 1;
return 0;
}
int judge(int kim)
{
if (check(kim) == 1)return 1;
int tot = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (a[i][j] == 0) {
a[i][j] = kim;
if (check(kim) == 1)tot++;
a[i][j] = 0;
}
}
}
if (tot >= 2)return 1;
else return 0;
}
int main(void)
{
int t;
scanf("%d", &t);
while (t--) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
char tmp[5]; scanf("%s", tmp);
if (tmp[0] == '.')a[i][j] = 0;
else if (tmp[0] == 'x')a[i][j] = 1;
else a[i][j] = 2;
}
}
char tmp[5]; scanf("%s", tmp);
int kim;
if (tmp[0] == '.')kim = 0;
else if (tmp[0] == 'x')kim = 1;
else kim = 2;
int flag = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (a[i][j] == 0) {
a[i][j] = kim;
if (judge(kim) == 1)flag = 1;
a[i][j] = 0;
}
}
}
if (flag == 1)printf("Kim win!\n");
else printf("Cannot win!\n");
}
return 0;
}