解题报告:Alice和Bob在做一个取石子游戏,有一堆n个石子,然后规定每个人每次最少要去1个石子,最多可以取m个石子,最后一次取完石子的人为胜。
巴什博奕,关键是找到必胜点和必败点,我们可以先列举出当n和m都比较小的情况,下面 以1代表第一个取的人为胜,0表示第一个取的人为负:
n <= m 1
n == m+1 0
n == m+2 1
..............
n == 2*m+1 1
n == 2*m+2 0
下面解释一下:当n小于m的时候,很显然,是第一个人胜利,当n 等于m+1的时候,由于第一个人至少都要取一个,取完一个之后,只剩下m个,第二个人可以一次取完,输了。于是我们可以确定,不管是谁到达这个m+1这个点,则可以判断,这个人一定会输。而当 m+1 < n < 2*m+ 2 时 ,由于第一个人可以一次取掉,从而可以使剩余的石子数为m+1所以当 m+1 < n < 2*m+ 2 时,第一个取的人一定会赢,然而,当n == 2*m + 2 时,不管第一个人是拿一个也好,拿2到m个也好,剩余的石子数一定会在 m+1 < n < 2*m+ 2 之间,这就直接导致了第二个人处于这个有利的地位,所以第一个人就输了。。。。。以此类推,可以总结出,当n 等于i个m+i的时候(i为正整数),第一个取的人一定是输的。
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 5 int main() 6 { 7 int n,m,T; 8 scanf("%d",&T); 9 while(T--) 10 { 11 scanf("%d%d",&n,&m); 12 if(m != 1) 13 { 14 int i; 15 for(i = 1;(m+1)*i<=n;++i) 16 if((m + 1) * i == n) 17 break; 18 printf((i == n/(m+1)+1)? "first\n":"second\n"); 19 } 20 else printf( n & 1? "first\n":"second\n"); 21 } 22 return 0; 23 }