Description
给定两个4位的质数a和b,从a开始每次只能改变a的一个数字,并且改完后的a还是质数,求a最少经过几次变换能得到b
Input
多组用例,第一行为用例组数n,之后n行每行两个四位质数
Output
对于每组用例,输出最少变换数,如果不能变成b则输出impossible
Sample Input
3
1033 8179
1373 8017
1033 1033
Sample Output
6
7
0
Solution
典型bfs
Code
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
#define maxn 10000
bool is_prime[maxn];
bool vis[maxn];
int num[maxn];
int start,end;
int n;
void bfs(int x)
{
queue<int>P;
P.push(x);//a入队
while(!P.empty())
{
int t=P.front();//出队
if(t==end)//变成b
return ;
vis[t]=true;//标记
P.pop();
char ch[5];
sprintf(ch,"%d",t);//将t转化成字符串好处理
for(int j=0;j<4;j++)//枚举换的四个位置
{
for(int k=0;k<10;k++)//每个位置枚举变换的值
{
int temp;
if(j==0&&k==0)//不能将最高位换成0
continue;
if(j==0)//换千位
temp=k*1000+(ch[1]-'0')*100+(ch[2]-'0')*10+(ch[3]-'0');
else if(j==1)//换百位
temp=k*100+(ch[0]-'0')*1000+(ch[2]-'0')*10+(ch[3]-'0');
else if(j==2)//换十位
temp=k*10+(ch[0]-'0')*1000+(ch[1]-'0')*100+(ch[3]-'0');
else if(j==3)//换个位
temp=k+(ch[0]-'0')*1000+(ch[1]-'0')*100+(ch[2]-'0')*10;
if(is_prime[temp]&&!vis[temp]&&temp<10000)//是素数就换
{
num[temp]=num[t]+1;//步数加一
vis[temp]=true;//标记该素数
P.push(temp);//将该素数进队
}
}
}
}
}
int main()
{
for(int i=0;i<10000;i++)//打素数表
is_prime[i]=true;
is_prime[0]=is_prime[1]=false;
for(int i=2;i<100;i++)
if(is_prime[i])
for(int j=2;i*j<10000;j++)
is_prime[i*j]=false;
cin>>n;
while(n--)
{
cin>>start>>end;
memset(vis,false,sizeof(vis));//初始化标记数组
memset(num,0,sizeof(num));//初始化步数
bfs(start);
if(num[end]==0&&start!=end)//a不能变成b
cout<<"impossible"<<endl;
else//可以则输出最少变换数
cout<<num[end]<<endl;
}
return 0;
}