pku2234 Matches game!!!!! hdu1846 brave game. if(n%(m+1)==0)n是必败点 !!!!!! pku2484 A Funny Game. if(n>=3)n是必败点 !!!!!! hdu1851 A Simple Game!!!!!! for(i=1,s=0;i<=n;i++){scanf("%d%d",&m,&l);s^=m%(l+1);} hdu1847 GoodLuck in CET-4 Everybody.if(n%3==0)n是必败点 hdu1730 Northcott Game hdu1517 A Multiplication Game,ecjtu1038 hdu1525 Euclid's Game pku2348,ecjtu1039 hdu2147 kiki's game hdu1907 John 取尽者败 pku3480 if(a1=a2=...=an=1) n为奇数必败,否则s=a1^a2...^an hdu2509 Be the Winner 取尽者败.zju1616 ,ecjtu1108 pku2068 nim-2n个人的game.ecjtu1112. pku1740 A New Stone Game. pku1704 Georgia and Bob pku2975 Nim-有多少种win的策略 hdu2176 取(m堆)石子游戏-有多少种win的策略 pku2368 Buttons ecjtu1006 Stone Game 放(1堆)石子游戏 hdu1729 Stone Game 放(n堆)石子游戏 hdu2516 取(2倍)石子游戏 hdu2580 a simple stone game(取k倍) pku1082 Calendar Game hdu1848 Fibonacci again and again 。ecjtu1113 hdu1536(hdu1944,pku2960,ecju1110) S-Nim ecjtu1116 Fibonacci again nuaa1516,ecjtu1117 质数取石子 pku2348,ecjtu1039 Euclid's Game pku2234 Matches game 取石子游戏 两个人面队若干堆石子(或硬币,火柴,棋子)进行游戏。各堆含有 a1,a2,…,ak枚硬币。 游戏规则如下: 1. 两人轮流取子,当轮到你取子时,你不能不取 2. 取子者只能从某堆中取子,取走一堆中的任意个子 3. 最后取子者为游戏的得胜者,或当轮到你取子时,你没有子可取 你为败者。 : 结论1. 如果只有一堆,即k=1,则第一取子者胜; 结论2. 如果只有2堆,a1,a2, a1=a2则第2取子者胜; 第1取子者在某堆取走c个,则 第2取子者在另1堆也取走c个, 2堆仍然相等。 即 第1取子者取后2堆不相等, 第2取子者取后2堆相等,最后 取子者是 第2取子者. 结论3. 如果只有2堆,a1,a2, a1<>a2则第1取子者胜; 第1取子者在多的1堆取 abs(a1-a2)个,取后2堆相等。 定义: 如果有k堆,堆数用无序向量(a1,a2,...,ak)表示,如果第1 取子者不能获胜,则称 (a1,a2,...,ak)为必败点. 例 . k=2时,(a,a) 为必败点 结论4: 无序向量(a1,a2,...,ak),如果经过1次取子后变为必败点 则(a1,a2,...,ak)为必胜点, 无论如何取都不能变为必败点,则为 必败点 。 例 . k=2时,(20,25) 为必胜点 ,1次取子后变为必败点(20,20) k=3 ,(20,20,25) 为必胜点 ,1次取子后变为必败点(20,20) k=2,(20,20),无论如何取都变不了必败点,(20,20) 是必败点。 k=2时,相同(相等)必败,不等必胜。 看看C语言的异或运算^ 性质1.若a=b,则a^b=0; 性质2.若a<>b,则a^b<>0; 性质3.若a^b=c,则a^c=b; a^a^b=a^c ==> b=a^c; 性质4.令s=a1^a2^...^an,si是a1,a2,...,an中除 ai以外的其余n-1个 的异或值, 则 si=s^ai 性质5.令s=a1^a2^...^an. 若 s=0,则 si=ai ,(i=1,2,...,n ) 当ai发生变化后,s<>0; 性质6.令A=(a1,a2,...,an),B=(b1,b2,...,bm,C=(a1,a2,...,an,b1,b2,...,bm). 记为C=A+B. 若A,B是必败点,则C是必败点 若A,B中有一个是必败点,另1个是必胜点,则C是必胜点. 两个必胜点之和不必是必胜点. 定义:若A+B是必败点,则称A与B等价 若A==B, 则A与B等价 性质7. A+A 是必败点。 3^5 =? 在C程序中 用printf("%d\n",3^5); 就知道了 异或运算^是:相同为0,不同为1 ,不进位 3,5的2进制数是 011,101 0 1 1 1 0 1 ------------------------ 1 1 0 因此 3^5=6 =(110)2进制 利用或运算^,结论2,结论3为 结论2‘k=2,如果a1^a2=0, 则第2人胜 结论3‘k=2,如果a1^a2<>0, 则第1人胜 k>2 如何 ? k=3. (a1,a2,a3) =(3,6,9) 3^6=5, 3^6^9=5^9<>0 对 (3,6,9)取子变为 (3,6,5) ,3^6^5=5^5=0 对 (3,6,5)无论如何取子都不能使其异或为0 一般地 有 定理 令s=a1^a2^...^ak,si=s^ai, (1)若s<>0,则存在 i,将 ai缩小为si后 s=0; (2)若s=0,则 将任何数ai做任何缩小后 s<>0; #include <stdio.h> int main() { int m,n,s;//n<=1000000 while(scanf("%d",&m)!=EOF) { s=0; while(m--) { scanf("%d",&n); s=s^n; } if(s==0)printf("No\n"); else printf("Yes\n"); } return 0; }有m堆石子,各堆有n颗石子。 hdu1851A Simple Game 方法: 这里采用的对每个事件中的每组数据 ,先用第一个数对比第二个数大1的数求余,再对各余数异或; 如果得到各个余数的异或值为零则有 Agrael胜得,对应的输出"Yes",反之输出“No”; 假设每次输入的数据为m,l;则有s=m1%(l1+1)^m2%(l2+1)^m3%(l3+1)^…………^mn%(ln+1); 当s=0时,输出Yes; 当s!=0 时输出No; 例 m1=100 ,l1=16 m2=98, l2=8 有 m1%(l1+1)=15;m2%(l2+1)=8; 得 15^8!=0; 所以这里会输出 “No ”; 怎么样理解呢? 因为只有当异或等于0时,这里是必胜点 ;当在这一点时,对方怎么拿都不能达到必胜点;当对方拿多少时 自己在另一处也拿多少,可以维持着处于必胜的局面; 但是在以上这一点时,当对方 在一堆中拿中 7个后,就变成好对方的必胜点;自己就必败了; #include<stdio.h> int main() { int T,n,m,s,l; scanf("%d",&T); while(T--) { scanf("%d",&n); s=0; while(n--) { scanf("%d%d",&m,&l); s^=m%(l+1); } if(s==0)printf("Yes\n"); else printf("No\n"); } return 0; } hdu1525 Euclid's Game pku2348 fun(int a ,int b)//a>=b { if( a%b==0)return 1; k=a/b;r=a%b;//a=k*b+r 25 7 ,7 4, 11 7 if(k>1)return 1; return 1-fun(b,r); } pku1740 A New Stone Game a1,a2,a3…………an为必败点<=>当n为偶数时,对a1--an进行从小到大或 从大到小排序,如果有a1=a2,a3=a4,…………an-1=an, 当n为奇数时以及其它的情况则必胜。 pku1704 Georgia and Bob. 将p[]排序. s=(p[n]-p[n-1])^(p[n-2]-p[n-3])^....^(p[2]-p[1]) if(n%2==1 ) 将 ^(p[2]-p[1])改为 ^(p[1]-p[0]),p[0]=0; pku2975 Nim-有多少种win的策略 解题报告: 取石子问题 此题求第一次取时能够得到必胜的取法; 首先我们按照公式对所有的石子的异或值S=a1^a2^a3.....^an; 若异S==0则说明是必败点。 输出 0; 若S不等于0; 则对第i堆石子 我们求出除去第i堆石子其余石子的异或值(以 7 11 13为例) 其中 对第1堆 我们求出11^13=6 则只要把第1堆中拿去1个 变成 6个 既OK 同理 对第2堆 我们求7^13=10 则只要把第2堆中拿去1个 变成 10个 既OK .... 那么总结出 设 Si=a1^a2^a3....ai-1^ai+1^ai+2....an; (除去第i堆石子其余石子的异或值) 若Si<ai 则说明我们可以找到一种取胜方法 for(i=1,num=0;i<=m;i++) { k=s^a[i];//s=a[1]^a[2]^...^a[n] if(k<a[i])num++; } ecjtu1006 Stone Game 放(1堆)石子游戏 f[d]=d*(d+1): 2,6,12,20,30,42,56 if(s<=f[d]&&s>f[d-1])s的必败点是 d-1; s=1000,1000 的必败点是31,31的必败点是5,5的必败点是 1 hdu1729 Stone Game 放(n堆)石子游戏 s1,c1;s2,c2;...sn,cn; bi是>=ci的最小必败点,ai=bi-ci; s=a1^a2^...^an hdu2516 取(2倍)石子游戏 1,2,3,5,8,13都是必败点,斐波那契数列中的数都是必败点。 hdu2580 a simple stone game(取k倍) a[i]=i,i<=k+1是必败点, 必败点a[i+1]=a[i]+a[p],k*a[p]>=a[i],k*a[p-1]<a[i]; pku1082 Calendar Game hdu1848 Fibonacci again and again .ecjtu1113 。3堆 int F(int k) { int g[15],i;//计算k的等价类数E[k], /* k个石子,取子后变为 b[j]=k-a[j]个 b[1],b[2],...,b[s] ,和b[j]等价的最小数是 E[b[j]] E[b[1]],E[b[2]],...,E[b[s]] E[k]= E[b[j]]中没有出现的最小数 . 必败点等价于0; k=fib[1],E[k]=1; */ for(i=0;i<15;i++)g[i]=0; for(i=1;a[i]<=k;i++)g[E[k-a[i]]]=1; for(i=0;i<=k;i++)if(g[i]==0)return i; } hdu1536(hdu1944,pku2960,ecju1110) S-Nim freopen("data1.in","r",stdin); S{2,3} ecjtu1116 Fibonacci again F[i]=0,i是必败点; F[i]=1,i是必胜点; i是 Fibonacci数,F[i]=1; if(F[i]==0) { for(j=1;fib[j]<=i;j++)if(F[i-fib[j]]==0){F[i]=1;break;}} nuaa1516,ecjtu1117 质数取石子
原文地址<http://code.google.com/p/zldry88-acm/issues/detail?id=7>