解题思路:
(1)题目还是比较容易懂的,但是操作起来有一些难度,有两堆石子块儿,每次只能从大的里面取小的数量的整数倍,然后一直到有一方全部拿空便为取胜。
(2)里面有一句特别关键的话,叫做两个人都采取最优策略,这是什么意思呢?意思当式子数量确定的时候,两个人都已经经过精确的计算,每一步应该怎么拿,然后确保自己能够胜利,如果还是很抽象,那么看一下示例:
对于25和7是有4种方案的,并且不同的方案赢的选手也不一样,但是题目说,选手都会按照最优策略来取,所以选手1保证赢的话,会按照第二种方案,这样先手赢
(3)这道博弈论的题为什么会出现在搜索里呢?因为每次取都会按照较小值的整数倍来取,需要枚举每一种方案。设dfs(a,b)函数为取的两堆石子块,(a>=b),递归出口为当a%b==0的时候,那么就可以一次取完a,获胜。
(4)如何判断是先手赢还是后手赢呢?可以设置一个计数器,可以发现,如果a%b==0的时候,如果当前是偶数的时候,表示是选手2取,那么后手赢,反之先手赢
(5)题目中还有一条特别关键的信息,叫做a/b>=2的时候,先手必赢,那么递归出口便增加了一个条件,这样会大大缩小时间复杂度(想想为什么呢?)
#include<bits/stdc++.h>
using namespace std;
int a,b;
bool flag;//用来标记先手是否赢
void dfs(int x,int y,int cnt)
{
if(x<y)
swap(x,y);
if(x%y==0||x/y>=2)//如果x能被y整除,即把x全部取掉胜利
{
if(cnt%2==1)//如果是奇数,说明是先手最后取的
flag=1;//打上标记
return ;//递归出口
}
else
{
for(int i=1;i<=x/y;i++)//枚举可以取的整数倍
{
dfs(x-i*y,y,cnt+1);//继续下一次递归
}
}
}
int main()
{
while(1)
{
cin>>a>>b;
if(a==0&&b==0)//结束条件
break;
dfs(a,b,1);//开始深搜
if(flag==1)
cout<<"win"<<endl;
else
cout<<"lose"<<endl;
flag=0;//标记初始化
}
return 0;
}