ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ3126 Prime Path(BFS+线性筛/埃氏筛)

2021-04-08 22:30:37  阅读:201  来源: 互联网

标签:Prime 埃氏 cout bb int BFS num primes include


题目传送门

这道题给出了两种做法:

首先当然要请出我们可爱的线性筛:

int primes[N], cnt;     // primes[]存储所有素数
bool st[N];         // st[x]存储x是否被筛掉

void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}


/*作者:yxc
链接:https://www.acwing.com/blog/content/406/
来源:AcWing
*/

1.按位BFS素数
这个思路比较基础,就是利用了BFS的“最短性质",推出来的:
枚举每一位,将每一位改成其他数,然后把它送入队列当中去,每一次BFS的过程中,都将它和标准数据做一个对比,如果是一致的那么就结束,并输出,如果最后队列空了,还没有找到,那么就输出”impossble"。
思路比较简单,下面看ac代码:

#include<iostream>
#include<cstring>
#include<queue>
#define N 10000
using namespace std;
int primes[N], cnt;     
bool st[N];  
int num[12100];
bool stt[10000];
queue<int>q;
void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
       
    }
}

int main(){
	int T;
	cin>>T;
	get_primes(10000);
	///cout<<
	while(T--){
		while(q.size()){
			q.pop();
		}
		int a,b;
		cin>>a>>b;
		if(a==b){
			cout<<"0"<<endl;
			continue;
		}
		memset(num,0,sizeof num);
		memset(stt,0,sizeof stt);
		q.push(a);
		stt[a]=true;
		int u=0;
		while(q.size()){
			int aa=q.front();
			q.pop();
			//cout<<aa<<endl;
			for(int i=1;i<=9;i++){
				int bb=i*1000+aa%1000;
				if(bb==b){
					u=1;
					cout<<num[aa]+1<<endl;
					break;
				}
				if(!st[bb]&&!stt[bb]){
					stt[bb]=true;
					num[bb]=num[aa]+1;
					q.push(bb);	
				}
			}
			if(u)break;
			for(int i=0;i<=9;i++){
				int bb=(aa/1000)*1000+i*100+aa%100;
				if(bb==b){
					u=1;
					cout<<num[aa]+1<<endl;
					break;
				}
				if(!st[bb]&&!stt[bb]){
					stt[bb]=true;
					num[bb]=num[aa]+1;
					q.push(bb);	
				}
			}
			if(u)break;
			for(int i=0;i<=9;i++){
				int bb=(aa/100)*100+i*10+aa%10;
				if(bb==b){
					u=1;
					cout<<num[aa]+1<<endl;
					break;
				}
				if(!st[bb]&&!stt[bb]){
					stt[bb]=true;
					num[bb]=num[aa]+1;
					q.push(bb);	
				}
			}
			if(u)break;
			for(int i=0;i<=9;i++){
				int bb=(aa/10)*10+i;
				if(bb==b){
					u=1;
					cout<<num[aa]+1<<endl;
					break;
				}
				if(!st[bb]&&!stt[bb]){
					stt[bb]=true;
					num[bb]=num[aa]+1;
					q.push(bb);	
				}
			}
			if(u)break;
		}
		if(u==0){
			cout<<"Impossible"<<endl;
		}
	}
	return 0;
}

2.按照素数进行BFS

思路较为相同,但是思考顺序发生了改变:
每一次进行搜索,找到所有和这个数只差一位的素数,让它们入队,最后返回的是我们这个数的结果。

#include <iostream>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <queue>
#include <utility>
#define me memset 

using namespace std;

typedef long long ll;

const int N = 10010;
const int null = 0x3f3f3f3f;

int T,a,b;
int d[N];
int primes[N],cnt;
bool st[N];

void get_primes()
{
    for (int i = 2; i <= 10000; i ++ )
    {
        if (st[i]) continue;
        primes[cnt ++ ] = i;
        for (int j = i + i; j <= 10000; j += i)
            st[j] = true;
    }
}

bool check(int x,int y)
{
	int usa = 0;
	while(x && y)
	{
		int i = x % 10,j = y % 10;
		
		if(i != j) usa ++;
		
		x /= 10;
		y /= 10;
	}
//	cout << usa << endl;
	
	if(usa == 1) return true;
	else return false;
}

int bfs()
{
	queue<int> q;
	me(d,-1,sizeof d);
	
	q.push(a);
	d[a] = 0;
	
	while(q.size())
	{
		int t = q.front();
		q.pop();
		
		for(int i = 168;i < cnt ;i ++)
		{
			if(check(primes[i],t) && d[primes[i]] == -1)
			{
				q.push(primes[i]);
				d[primes[i]] = d[t] + 1;
			}
		}
	}

	
	return d[b];
}

int main()
{
	cin >> T;
	
	get_primes();
	
//	for(int i = 0;i < cnt;i ++) cout << primes[i] << endl;
	
//	cout << cnt << endl;
	
//	cout << primes[168] << endl;
	
	while(T --)
	{
		cin >> a >> b;
		
		if(a == b)
		{
			cout << "0" << endl;
			continue;
		}
		
	
		
	//	check(a,b);
		
		if(bfs()) cout << d[b] << endl;
		else cout << "Impossible" << endl;
		
		
	}
	
	return 0;
}

标签:Prime,埃氏,cout,bb,int,BFS,num,primes,include
来源: https://blog.csdn.net/m0_51841071/article/details/115532943

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有