题目链接
思路:BFS
简单模拟两个函数,然后通过BFS不断将当前可能的两种操作放入队列,只要变成了B就说明是最小次数,代码如下:
#include<bits/stdc++.h> using namespace std; #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int N=5005,mod=233; int vis[300]; const ll INF=999999999999999999; ll a,b; struct A{ ll now,num; }; ll P(ll x){ return ((x*x%mod*x)%mod+x*x%mod)%mod; } ll G(ll x){ return ((x*x%mod*x)%mod-x*x%mod+mod)%mod; } int main(){ int t; scanf("%d",&t); while(t--){ memset(vis,0,sizeof(vis)); scanf("%lld%lld",&a,&b); if(a==b){printf("0\n");continue;} if(b>=mod){printf("-1\n");continue;} queue<A>qqq; if(a>=233){ ll c=P(a); ll d=G(a); vis[c]=1;vis[d]=1; qqq.push(A{c,1}); qqq.push(A{d,1}); } else{ vis[a]=1; qqq.push(A{a,0}); } ll ans=INF; //把出现过的状态都标记一下,只入队没出现过的状态 while(!qqq.empty()){//队列不为空 A tmp=qqq.front(); qqq.pop(); if(tmp.now==b){ ans=tmp.num; break; } else { ll t1=P(tmp.now),t2=G(tmp.now); if(!vis[t1])qqq.push(A{t1,tmp.num+1}); if(!vis[t2])qqq.push(A{t2,tmp.num+1}); vis[t1]=1;vis[t2]=1; } } if(ans==INF)printf("-1\n"); else printf("%lld\n",ans); } }