【CF1451F】Nullify The Matrix
阿新 • • 發佈:2020-12-30
題目
題目連結:https://codeforces.com/problemset/problem/1451/F
給出一個 \(n\times m\) 的網格,每個格子上有一個非負數。
兩人輪流操作,每次操作選擇一個數字大於 \(0\) 格子 \((x,y)\) 開始,將 \((x,y)\) 減去一個正整數,並且修改完後 \((x,y)\) 依然非負。
然後選擇一條從 \((x,y)\) 開始只往右和往下的路徑,到任意格子結束,並且將除 \((x,y)\) 以外所有格子修改為一個非負數。
最先無法操作的人獲勝。問先手是否必勝。
\(Q\leq 10,n,m,\leq 100\)。
思路
考慮橫縱座標之和相同的格子形成的一條條斜線,如果選擇了格子 \((x,y)\)
找到第一個異或和不為 \(0\) 的斜線,根據 NIM 遊戲的證明我們知道,只要選擇異或和中最高位為 \(1\) 的那一個將它減小至異或和,這樣就使得異或和變為 \(0\)。
除此之外,我們操作了這個格子之後還可以改變後面所有斜線的異或和,所以如果存在一條斜線的異或和不為 \(0\),我們就可以通過一次操作把所有斜線的異或和變為 \(0\)。
接下來後手操作一定會變回存在一條斜線異或和不為 \(0\) 的情況,而目標狀態異或和為 \(0\),所以我們只需要判斷初始狀態是否存在一條斜線的異或和不為 \(0\) 即可。
時間複雜度 \(O(Qnm)\)
程式碼
#include <bits/stdc++.h> using namespace std; const int N=110; int Q,n,m,x,xors[N*2]; int main() { scanf("%d",&Q); while (Q--) { memset(xors,0,sizeof(xors)); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { scanf("%d",&x); xors[i+j]^=x; } x=0; for (int i=1;i<=n+m;i++) x+=xors[i]; if (x) printf("Ashish\n"); else printf("Jeel\n"); } return 0; }