Problem Description
Alice and Bob are playing a new game that is a mixture of tic-tac-toe and nim.
There are 9 piles of stones forming a 3∗3 grid. Players take turns to remove the stones: in each turn, the player choose a remaining pile and remove a positive number of stones from it. Alice goes first. The first player to remove a pile so that a new empty row or column is formed wins. Notice that player does NOT have to be the one to remove all three piles to win, and diagonals does NOT count as a win.
However, to speed up the game, both players have decided they will always remove the whole pile they choose in their respective first turn, instead of removing only part of the pile. Now Alice wants to know how many different moves can she choose in the first turn so that she can still ensure her victory.
Input
The first line contains one integer T (1≤T≤500000), the number of test cases.
For each test case, there are 3 lines, each contains 3 integers aij (1≤aij≤109), denoting the number of stones in each pile.
Output
For each test case, output one integer denoting the answer. Output 0 when Alice can not win in the situation.
Sample Input
2
1 1 1
1 1 1
1 1 1
1 2 3
4 5 6
7 8 9
Sample Output
9
7
题意:
井字棋,A B轮流取,可以取一个格子里的一些石子,先取完一行或者一列获胜。
要求A B第一次取的时候必须取完一个格子。
求A是否必胜。
思路:
A取完一个格子后,有4个格子和它同行同列,如果B取了这几个中的一种,那么下次A再取完一个格子就赢了,所以B一定不会取和A同行同列的格子。
所以AB取了不同行不同列的两个格子,此时6个格子和A,B之前取的同行同列,1个格子和AB之前取的不同行不同列。
只要谁先取完了和A,B开头取的同行同列6个格子中的一个,谁就输了。
所以必败态是6个同行同列的格子为1,剩下一个不同行不同列的格子为0,这就是裸的nim博弈了。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 5005;
const int mod = 1e9 + 7;
int a[35][35];
int main() {
int T;scanf("%d",&T);
while(T--) {
int Xor = 0;
for(int i = 1;i <= 3;i++) {
for(int j = 1;j <= 3;j++) {
scanf("%d",&a[i][j]);
Xor ^= (a[i][j] - 1);
}
}
int ans = 0;
for(int i = 1;i <= 3;i++) {
for(int j = 1;j <= 3;j++) {
int flag = 1;
for(int ci = 1;ci <= 3;ci++) {
if(ci == i) continue;
for(int cj = 1;cj <= 3;cj++) {
if(cj == j) continue;
int num = Xor ^ (a[i][j] - 1) ^ (a[ci][cj] - 1) ^ (a[6 - i - ci][6 - j - cj] - 1) ^ (a[6 - i - ci][6 - j - cj]);
flag &= (num != 0);
}
}
ans += flag;
}
}
printf("%d\n",ans);
}
return 0;
}