POJ3126Prime Path(BFS入门+埃氏筛取素数法)

题目:传送门
分析:题意大概是给出两个素数(四位数),判断第一个素数是否能通过每次改变一位变为另一个素数,经过多次改变后变成第二个素数,每一位的情况都考虑为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的基本思路应该就是:设置一个队列,然后将初始状态放在第一位,每取出第一位然后依据题目条件对第一位相关的进行遍历,如果有符合条件的即放入队列中,直至队列为空或找到最优解。

猜你喜欢

转载自blog.csdn.net/weixin_43556295/article/details/86663309
今日推荐