题目:传送门
分析:题意大概是给出两个素数(四位数),判断第一个素数是否能通过每次改变一位变为另一个素数,经过多次改变后变成第二个素数,每一位的情况都考虑为BFS
思路:先把素数打印出来,可以用埃氏筛法,需要了解可以点击埃氏筛法简单模板这一篇blog有容易理解的介绍,接着就是对每一位的情况进行遍历了,即BFS。
AC代码:
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
#include<iostream>
using namespace std;
int prime[10000],d[10000]; //用d[]来记录最短路径
bool is_prime[10001]; //素数判断
void sieve(){
int p=0;
for(int i=0;i<=9999;i++) is_prime[i]=true;
is_prime[0]=is_prime[1]=false;
for(int i=2;i<=9999;i++){
if(is_prime[i]){
prime[p++]=i; //存取素数(本题没啥用就是模板来的)
for(int j=2*i;j<=9999;j+=i) //将素数的倍数标记
is_prime[j]=false;
}
}
}
int bfs(int a,int b){
queue<int>que;
que.push(a);
d[a]=0;
while(que.size()&&d[b]==-1){
int now=que.front(); que.pop();
int tem=1;
for(int i=1;i<=4;i++){ //这个遍历挺巧妙的(看了别人的代码的)
for(int j=0;j<=9;j++){
if(i==4&&j==0) continue;
int nex=(now/(tem*10))*(tem*10)+tem*j+now%tem;
if(is_prime[nex]&&d[nex]==-1){ //判断是不是素数以及有没有走过
d[nex]=d[now]+1;
que.push(nex);
}
}
tem*=10;
}
}
return d[b];
}
int main(){
sieve();
int t,x,y;
cin>>t;
while(t--){
cin>>x>>y;
memset(d,-1,sizeof(d));
if(bfs(x,y)==-1) cout<<"Impossible"<<endl;
else cout<<bfs(x,y)<<endl;
}
}
小结:学了BFS后做的第一道,比较入门,总结一下BFS的基本思路应该就是:设置一个队列,然后将初始状态放在第一位,每取出第一位然后依据题目条件对第一位相关的进行遍历,如果有符合条件的即放入队列中,直至队列为空或找到最优解。