题目链接:https://vjudge.net/problem/POJ-3126
题解:给两个数,判断如果只改变一个位数且只为素数的话,最少经过几步到达另一个数。如果无法到达,便输出imposs
最短路径问题,可以用dfs来写,需要注意一个地方,不会仅存在只改变他们不同的位置,因此需要从1到9遍历。
代码:
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#define maxn 10050
#define INF 10000000
using namespace std;
int fl[maxn];
int a[4]={1,10,100,1000};
int en[4],be[4];
int ans[maxn];
int beginn,endd;
queue<int>que;
void sushu()//素数筛选法
{
for(int i=2;i<=maxn-50;)
{
for(int j=i+i;j<=maxn-50;j+=i)
fl[j]=1;//非素数是1
for(i++;i<=maxn-50&&fl[i];i++);//寻找下一个素数
}
}
void dfs()
{
int ff=1;
que.push(beginn);
ans[beginn]=0;
while(!que.empty())
{
int p=que.front();
int pp=p;
que.pop();
if(p==endd)
{
ff=0;
cout<<ans[endd]<<endl;
break;
}
int q=0;
while(pp!=0)
{
be[q]=pp%10;
pp/=10;
q++;
}
for(int i=1;i<=9;i++)//循环千位数字
{
if(i==be[3])
continue;
int k=p-be[3]*a[3]+i*a[3];
if(ans[k]==INF&&fl[k]==0)
{
ans[k]=ans[p]+1;
que.push(k);
}
}
for(int i=0;i<3;i++)//循环百十个位
{
for(int j=0;j<=9;j++)
{
if(j==be[i])
continue;
int k=p-be[i]*a[i]+j*a[i];
if(ans[k]==INF&&fl[k]==0)
{
ans[k]=ans[p]+1;
que.push(k);
}
}
}
}
if(ff==1)
cout<<"Impossible"<<endl;
}
int main()
{
int k;
memset(fl,0,sizeof(fl));//素数是0
sushu();
cin>>k;
while(k--)
{
for(int i=0;i<maxn;i++)
ans[i]=INF;//标志量
cin>>beginn>>endd;
int cou=0,e=endd;
while(e)//储存每一位
{
en[cou]=e%10;
e/=10;
cou++;
}
while(!que.empty())
que.pop();
dfs();
}
return 0;
}