摘要: /*无环图,树计算 sg值,求出每个节点处得sg值来*/#include <cstdio>#include <vector>using namespace std;int N,M,Q;int sg[1010];vector<int> G[1010];int dfs(int x){ int& cur = sg[x]; if(cur!=-1) return cur; cur = 0; bool used[1010]={0}; for(int t,i=G[x].size()-1;i>=0;i--) { used[ dfs(G[x][i]) ] = 1 阅读全文
posted @ 2011-06-16 23:51 AC2012 阅读(206) 评论(0) 推荐(0) 编辑
摘要: /*指定一个数 nn ~ oo 是必败态n/9 - n-1 必胜n/18 ~ n/9 必败n/(18*9) ~ n/18-1必胜态n/(18*18) ~ n/(18*9) 必败对于这个题目,很明显的需要用到必胜态和必败态来判断。而且n很大,所以不可能用数组求,所以只能找规律对于n及比n大的数是必败态所有能够转到必败态的状态都是必胜态所以n/9 ~ n-1就是必胜态了所有全部到达必胜态的状态是必败态所以n/18 ~ n/9 就是必败态,可以用一个区间来表示。这里需要注意边界,这里我没有考虑*/#include <cstdio>int n,ans;int main(){ while(s 阅读全文
posted @ 2011-06-16 14:08 AC2012 阅读(181) 评论(0) 推荐(0) 编辑
摘要: /*K个石块,L最大取值。问L取什么样的值,可以保证第二个选手赢1 ~ L 必胜L+1 必败L+2 ~ L+L+1 必胜L+L+2 必败L+L+3 必胜 L+L+2+L必胜L+L+L+3 必败4L+45L+5通过找规律发现,必败态的条件是满足 tL+t,所以我们可以对K找因子,找到最小的那个L就可以了*/#include <cstdio>int K,L;#define min(x,y) ((x)<(y)?(x):(y))int main(){ while(scanf("%d",&K)==1) { int ans = 1000000000; for( 阅读全文
posted @ 2011-06-16 13:14 AC2012 阅读(180) 评论(0) 推荐(0) 编辑
摘要: /*一个很有意思的问题。初看好像不好做。在看,可以转化是取石子问题。因为对于任意一堆数a,b。大的可能是小的好几倍,所以从a上取b可以取多个,然后才能转化为以b为大,a%b为小的下一堆。问题可以转化为:若干堆石子,最后一堆只有一个石子,现在要求从左开始取,只有前一堆取完才能取下一堆。谁取到最后一个石子算胜。可以使用必胜态必败态来做。假设石子数量是1 4 5 1从右往左推,1是必胜态,因为轮到自己的时候,可以执行一步操作就到达要求的目标。 5是必胜态,因为我可以只取4个,然后剩下一个给对方,然后就可以转到下一个必胜态。 4是必胜态,因为我可以只取3个,然后剩下的一个对对方,然后就可以转到下一个必 阅读全文
posted @ 2011-06-16 11:01 AC2012 阅读(232) 评论(0) 推荐(0) 编辑
摘要: /*NIM基础题*/#include <cstdio>int N,A[200001],ans;int main(){ while(scanf("%d",&N)==1) { if(!N) break; ans = 0; for(int i=0;i<N;i++) { scanf("%d",A+i); ans ^= A[i]; } if(ans){printf("Yes\n"); for(int i=0;i<N;i++) { if( A[i]>=(ans^A[i]) ) { printf("% 阅读全文
posted @ 2011-06-16 01:36 AC2012 阅读(283) 评论(0) 推荐(0) 编辑
摘要: /*Nim游戏,首先求出sg异或和的值。如果是胜,判断每堆石块通过变化个数能够达到败态。计数就可以了*/#include <cstdio>int N,A[1010],ans;int main(){ while(scanf("%d",&N)==1) { if(!N) break; ans = 0; for(int i=0;i<N;i++) { scanf("%d",&A[i]);ans^=A[i]; } int cnt=0; if(ans) for(int i=0;i<N;i++) { if( A[i]>= ( 阅读全文
posted @ 2011-06-16 01:22 AC2012 阅读(135) 评论(0) 推荐(0) 编辑
摘要: /*NIM游戏基础*/#include <cstdio>int N,a,ans;int main(){ while(scanf("%d",&N)==1) { ans = 0; for(int i=0;i<N;i++) { scanf("%d",&a); ans ^= a; } if(ans) printf("Yes\n"); else printf("No\n"); } return 0;} 阅读全文
posted @ 2011-06-16 00:54 AC2012 阅读(130) 评论(0) 推荐(0) 编辑
摘要: /*由于任何两个相邻的棋子只与他们之间的空为有关。这些空位可以看做是石子数,谁取得了最后一个空位(石子)就是赢家,所以是转化为了普通的NIM游戏。*/#include <cstdio>#include <algorithm>using namespace std;int T,N;int d[1010];int main(){ scanf("%d",&T); while(T--) { scanf("%d",&N); for(int i=0;i<N;i++) scanf("%d",d+i); 阅读全文
posted @ 2011-06-16 00:32 AC2012 阅读(169) 评论(0) 推荐(0) 编辑