标签:style icpc data cal lse ons 初始 for 答案
题目链接:https://codeforc.es/gym/101908/problem/B
题意:两个人玩游戏,有 n 块石头,初始坐标为(x,y),一次操作可以将一块石头移动到(x - u,y),(x,y - u)或者(x - u,y - u),坐标为(0,0)的石子不能移动,问先手赢还是输。
题解:显然移动石子不能移动到 x = 0,y = 0 或者 x = y 的直线上,否则下一个玩家通过一步就可以获胜,故求 sg 值的时候,遇到这些坐标上的点直接跳过,答案则为全部石子异或和,特批一下一开始是否有在 x = y 直线上的石子即可。
1 #include <bits/stdc++.h> 2 #define sd(a) scanf("%d",&a) 3 #define sld(a) scanf("%lld",&a) 4 #define mst(a,b) memset(a,b,sizeof a) 5 #define pb push_back 6 #define mp make_pair 7 typedef long long ll; 8 using namespace std; 9 typedef pair<int,int> pii; 10 const int maxn = 1e3 + 10; 11 int inf = 0x3f3f3f3f; 12 13 bool vis[210]; 14 int sg[110][110]; 15 16 void getsg() { 17 mst(sg, 0); 18 for(int i = 1; i <= 100; i++) { 19 for(int j = 1; j <= 100; j++) { 20 if(i == j) continue; 21 mst(vis, false); 22 int mx = max(i, j); 23 for(int k = 1; k <= mx; k++) { 24 if(i > k && (i - k) != j) vis[sg[i - k][j]] = true; 25 if(j > k && (j - k) != i) vis[sg[i][j - k]] = true; 26 if(i > k && j > k) vis[sg[i - k][j - k]] = true; 27 } 28 for(int k = 0; ; k++) { 29 if(!vis[k]) { 30 sg[i][j] = k; 31 break; 32 } 33 } 34 } 35 } 36 } 37 38 int main() { 39 #ifdef local 40 freopen("data.txt","r",stdin); 41 #endif // local 42 // init(); 43 getsg(); 44 int n; 45 scanf("%d",&n); 46 int flag = 0; 47 int ans = 0; 48 for(int i = 0; i < n; i++) { 49 int x,y; 50 scanf("%d%d",&x,&y); 51 if(x == y) flag = 1; 52 ans ^= sg[x][y]; 53 } 54 if(flag || ans) puts("Y"); 55 else puts("N"); 56 return 0; 57 }
2018-2019 ACM-ICPC Brazil Subregional Programming Contest B. Marbles
标签:style icpc data cal lse ons 初始 for 答案
原文地址:https://www.cnblogs.com/scaulok/p/9866723.html