题目链接
思路: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);
}
} 


京公网安备 11010502036488号