题意:将一个初始数字变成目标数字,每次只能改变一个数字,并且保证每一个改变后的数字是是素数,求最少的步数。
分析:一般求最少步数都是用广搜,这是个简单广搜。
代码:
#include<iostream>
using namespace std;
#define maxn 1000000
int que[maxn],first,rear;
int inque[10000]; //表示这个数是否访问过了并且存储步数
bool Isprime(int a) //判断一个数是否是素数
{
for(int i=2; i*i<=a; i++)
if( a%i==0)
return false;
return true;
}
void Solve(int i,int a,int temp,int num)
{
if( i!=a&&!inque[temp-1000]&&Isprime(temp)){ //如果此数没有访问过标志并设置为num的下一步。
inque[temp-1000]=inque[num-1000]+1;
que[rear++]=temp;
}
}
int BFS(int start,int goal) //广搜遍历寻找 最短的路径
{
int i,temp,num,cnt,a,pt;
first=rear=0;
cnt=0; pt=0;
memset(que,0,sizeof(que));
memset(inque,0,sizeof(inque));
que[rear++]=start;
inque[start]=1;
while( first!=rear){
num=que[first++];
if( num==goal)
return inque[goal-1000];
for( i=0; i<=9; i++){
if( i!=0){ //改变首位,不为0
a=num/1000;
temp=num-a*1000+i*1000;
Solve(i,a,temp,num);
}
a=num%1000; //第二位
if(a/100) a/=100;
else a=0;
temp=num-a*100+i*100;
Solve(i,a,temp,num);
a=num%100; //第三位
if(a/10) a/=10;
else a=0;
temp=num-a*10+i*10;
Solve(i,a,temp,num);
a=num%10; //第四位
temp=num-a+i;
Solve(i,a,temp,num);
}
}
}
int main()
{
int s,t,g;
scanf("%d",&t);
while( t--){
scanf("%d%d",&s,&g);
if( s==g)
printf("0\n");
else
printf("%d\n",BFS(s,g));
}
return 0;
}