该题第一思路是直接使用搜索解决,即使用dfs模拟整个游戏的过程,对于判断是否平局则通过回合数进行判断,这里我暴力选择如果回合数>10000则判定为平局
#include<iostream> using namespace std; const int MAX=1e4+10; int t,mod; int dfs(int x,int y,int i){ if(i>10000){//平局 return 0; } if(x==0){ return 1; } if(y==0){ return 2; } if(i%2==0){ return dfs(x,(x+y)%mod,i+1); }else{ return dfs((x+y)%mod,y,i+1);//回合数为奇数时更新x } } int main(){ cin>>t>>mod; while(t--){ int x,y; cin>>x>>y; int ans=dfs(x,y,1); if(ans==0){ cout<<"error"<<endl; continue; } cout<<ans<<endl; } return 0; }
实际上该题还可以使用记忆化数组进行优化
即我们可以使用一个记忆数组s[x][y]记录下在出现x和y时最后是谁赢了,这样下次再碰见x和y就可以直接在数组里找到答案了,同时我们通过在纸上模拟样例1发现,在出现平局时必然会存在一个死循环即会回到开始的x和y,因此我们只需假设起点s【x】【y】=-1,那么再次出现x和y时判断即可返回平局的结果
#include<iostream> using namespace std; const int MAX=1e4+10; int t,mod; short s[MAX][MAX];//表示出现x=i,y=j,谁赢了,1表示甲赢了,2表示乙赢了 int dfs(int x,int y){ if(s[x][y]==-1){//记忆 return -1; } if(s[x][y]){//记忆 return s[x][y]; } s[x][y]=-1;//先假设为平局,这样的话如果真是平局的话还会递归回到相同的x和y此时便会真返回-1 //如果不是平局也没关系,后面会改变对应的值的 if(x==0){ return s[x][y]=1; } if(y==0){ return s[x][y]=2; } int temp1=(x+y)%mod;//下个回合 int temp2=(temp1+y)%mod;//下下个回合 return s[x][y]=dfs(temp1,temp2); } int main(){ cin>>t>>mod; while(t--){ int x,y; cin>>x>>y; int ans=dfs(x,y); if(ans==-1){ cout<<"error"<<endl; continue; } cout<<ans<<endl; } return 0; }