题目链接:http://poj.org/problem?id=3126
题意:
给出两个素数,判断能否将第一个素数转换为第二个素数。转换需遵循以下规则:每次只能改变一位数,且改变之后该数为素数,不允许出现前导0的情况。
思路:题目比较水..细心一点,按照要求慢慢拍代码就好。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=10010;
int T,n,m;
int prime[maxn];
bool vis[maxn];
void work(){//素数打表
memset(prime,0,sizeof(prime));
prime[1]=1;
for(int i=2;i<maxn;i++){
if(!prime[i]){
for(int j=i;i*j<maxn;j++){
prime[i*j]=1;
}
}
}
}
struct node{
int num;
int step;
};
int getNum(int *a){//数组转换成整数
int ans=0;
for(int i=0;i<4;i++){
ans=ans*10+a[3-i];
}
return ans;
}
bool Bfs(){
queue<node>q;
node s,e;
s.num=n,s.step=0;
vis[s.num]=1;
q.push(s);
while(!q.empty()){
s=q.front();
q.pop();
if(s.num==m){
printf("%d\n",s.step);
return true;
}
int a[4],temp[4];
int nowNum=s.num,cnt=0;
while(nowNum){
a[cnt]=nowNum%10;
nowNum/=10;
cnt++;
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++)
temp[j]=a[j];
for(int j=0;j<10;j++){
temp[i]=j;
e.num=getNum(temp);
e.step=s.step+1;
if(!vis[e.num]&&!prime[e.num]&&e.num>=1000){//注意判断前导0的情况
vis[e.num]=1;
q.push(e);
}
}
}
}
return false;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
work();
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
memset(vis,0,sizeof(vis));
bool flag=Bfs();
if(!flag) puts("Impossible");
}
return 0;
}