轉載:http://blog.csdn.net/bool_isprime/archive/2010/08/10/5801934.aspx
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]-1)^(p[n-2]-p[n-3]-1)^....^(p[2]-p[1]-1)
if(n%2==1 ) 將 ^(p[2]-p[1]-1)改為 ^(p[1]-p[0]-1),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 質數取石子