传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1846
分析:做博弈论类的题目,我觉得最关键的是分析极限条件。特别是这类游戏题目,我们假设最后时的情况,当还剩下m+1个石子时,轮到A拿石子,由于A至少要拿1个石子,所以不管A拿走多少个,剩下的可以由B全部拿走。此种情况下,A必败。此时我们扩展这种极限情况,当剩下k(m+1)个石子时,K为整数,这时实际上可以将问题分解为K个极限情况,由于双方都是绝对聪明的,假设此时轮到A拿,A不论拿任意x颗石子(大于1小于等于M),B都可以拿走m+1-x颗石子,使整堆石子剩下(k-1)(m+1),如此循环,到最后就是我们最开始列出的极限情况,此时A必败无疑。因此,我们解题的关键,或者说是制胜的关键就是让对方剩下k(m+1)个石子,由于绝对聪明,这种情况下对方将毫无疑问的输掉。
对于此题而言,当n <= m 时,first胜。当 n > first 时,如果 n = k(m+1) 即 n%(m+1) = 0 则second 胜,否则first胜。
程序如下:
Memory: 188 KB Time: 15 MS
Language: C Result: Accepted
This source is shared by hust_lcl
/*此题实际上是BASH GAME,关键是找寻取胜策略,搜寻极端情况
n = m + 1此时轮到A做出选择,因为可以拿的石子数为1-m
因此,无论A选择几个,剩下的m + 1 - k 个可以全部被B选走取胜
将此情况推广,取胜关键就是给对方留下m+1的整数倍个石子
轮到A时,如果n = (m + 1)*k + a个,则A选走a个
剩下的B选走k个 k<=m,然后A再选走m + 1 - k个 这样始终剩下m+1的
整数倍个给B,最终会到达n = m + 1个的情况,A取胜
*/
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c , n , m;
scanf("%d",&c);
while(c--)
{
scanf("%d%d",&n,&m);
if(n%(m+1)==0)
printf("second\n");
else
printf("first\n");
}
return 0;
}