题目连接:http://poj.org/problem?id=3126
题意:给定两个质数,求一条两者之间的最短质数路径。
这题用单BFS已经够了,但是,还是练习下双BFS吧。
代码:
#include<iostream>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<string>
#define LL __int64
#define INF 0xffffffff
using namespace std;
struct node{
int x,step;
};
int prime[10000],vis[2][10000],m,n;
void init(){
memset(prime,0,sizeof(prime));prime[0]=prime[1]=1;
for(int i=2;i<(int)sqrt(100000.5);i++) if(!prime[i])
for(int j=i*i;j<10000;j+=i) prime[j]=1;
}
void bfs(){
memset(vis,0,sizeof(vis));
queue<node> Q[2];
Q[0].push((node){m,0});Q[1].push((node){n,0});
vis[0][m]=1;vis[1][n]=1;
int deep=0;
while(!Q[0].empty() || !Q[1].empty()){
int i=0;
while(i<2){
node tp=Q[i].front();
if(tp.step!=deep){i++;continue;}
Q[i].pop();
int t[4];//获取每一位数字
t[0]=tp.x%10; t[1]=(tp.x/10)%10;
t[2]=(tp.x/100)%10; t[3]=(tp.x/1000);
for(int j=0;j<4;j++){//改变的位置
int y=0;
for(int k=3;k>=0;k--)//把需要改变的位置置为0
if(k!=j) y=y*10+t[k];
else y=y*10;
for(int k=0;k<10;k++){//枚举改变的位置的值
int ty=y+k*(int)pow(10,j);
if(vis[1-i][ty]) {cout<<(deep*2+i+1)<<endl;return;}
if(vis[i][ty] || prime[ty] || ty<1000) continue;
Q[i].push((node){ty,deep+1});
vis[i][ty]=1;
}
}
}
deep++;
}
}
int main(){
init();
int T;cin>>T;
while(T--){
scanf("%d %d",&m,&n);
if(m==n){cout<<0<<endl;continue;}
bfs();
}
return 0;
}