问题链接:Problem H
问题简述:
给出一个四位数质数,将其转化为另一个四位数质数,转化过程中只能改变一位数字,首位不得为0,且改变后四位数整体仍是质数,求最小转化步骤数。
问题分析:
求最短路径,首先想到的是BFS算法,有四个转移方向,个位,百位,十位,千位,由于每次转化后还须进行素数判断,所以可以先对1000~10000的素数进行打表。
程序说明:
以除法取模的方式分别得到个位,百位,十位,千位,将相应的位数置0后除千位外遍历0~9的情况,千位遍历1 ~ 9,以BFS算法即可求出最短转化路径步数。
AC通过的C++语言程序如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
int prime[10005];
bool vis[10005];
bool edge(int x){
if(prime[x]==0&&vis[x]==0&&x>=1000&&x<10000)
return 1;
else return 0;
}
struct node{
int n;
int t;
};
int BFS(int a,int b){
queue<node>q;
node p1;
p1.n=a;
p1.t=0;
vis[a]=1;
q.push(p1);
while(!q.empty()){
node p2=q.front();
q.pop();
if(p2.n==b){
return p2.t;
}
int n1=p2.n%10;
int n2=p2.n/10%10;
int n3=p2.n/100%10;
int n4=p2.n/1000%10;
for(int i=0;i<=9;i++){
if(edge(p2.n-n1+i)){
p1.n=p2.n-n1+i;
p1.t=p2.t+1;
vis[p2.n-n1+i]=1;
q.push(p1);
}
}
for(int i=0;i<=90;i+=10){
if(edge(p2.n-n2*10+i)){
p1.n=p2.n-n2*10+i;
p1.t=p2.t+1;
vis[p2.n-n2*10+i]=1;
q.push(p1);
}
}
for(int i=0;i<=900;i+=100){
if(edge(p2.n-n3*100+i)){
p1.n=p2.n-n3*100+i;
p1.t=p2.t+1;
vis[p2.n-n3*100+i]=1;
q.push(p1);
}
}
for(int i=1000;i<=9000;i+=1000){
if(edge(p2.n-n4*1000+i)){
p1.n=p2.n-n4*1000+i;
p1.t=p2.t+1;
vis[p1.n=p2.n-n4*1000+i]=1;
q.push(p1);
}
}
}
return -1;
}
int main(){
std::ios::sync_with_stdio(false);
memset(prime,0,sizeof(prime));
for(int i=2;i<10005;i++){
if(prime[i]==0){
for(int j=2*i;j<10005;j+=i){
prime[j]=1;
}
}
}
int c;
cin>>c;
while(c--){
memset(vis,0,sizeof(vis));
int a,b;
cin>>a>>b;
int ans=BFS(a,b);
if(ans>=0)
cout<<ans<<endl;
else
cout<<"Impossible"<<endl;
}
}