6.质数路径(简单搜索 BFS)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了6.质数路径(简单搜索 BFS)相关的知识,希望对你有一定的参考价值。

质数路径

题目链接

题目

给定两个四位质数 \\(A\\)\\(B\\) ,你需要通过最少的操作次数将 \\(A\\) 变为 \\(B\\) 。每次操作只能改变当前数的其中一位数字,并且每次操作过后,当前数必须仍然是一个质数。例如,将 \\(1033\\) 变为 \\(8179\\) ,最少需要进行 \\(6\\) 次操作,具体操作为:
1033 -> 1733 -> 3733 -> 3739 -> 3779 -> 8779 -> 8179
请计算并输出所需要的最少操作次数。

输入格式

第一行包含整数 \\(T\\) ,表示共有 \\(T\\) 组测试数据。
每组数据占一行,包含两个四位质数 \\(A\\)\\(B\\)

输出格式

每组数据输出一行答案,表示所需最少操作次数。
如果无法做到,则输出 Impossible
经实际测试,不存在无解情况,特此声明。

数据范围

\\(1≤T≤100\\)
\\(1000≤A,B≤9999\\),保证 \\(A\\)\\(B\\) 都是质数。

输入样例:

3
1033 8179
1373 8017
1033 1033

输出样例:

6
7
0

思路

从质数起点开始搜索,通过 \\(BFS\\) 每次向后每次扩展 \\(4*9=36\\) 种情况 ,同时更新最短距离

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int prime[N];
int d[N];//存最短距离
bool st[N];
int cnt;
void getprime(int n)//筛质数

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


void bfs(int x)

	memset(d,-1,sizeof d);
	queue<int>q;
	q.push(x);
	d[x]=0;
	
	while(q.size())
	
		auto t=q.front();
		q.pop();
		
		string s=to_string(t);
		for(int i=0;i<s.size();i++)//枚举每个位置
		
			for(char j=\'0\';j<=\'9\';j++)//枚举数字0-9
			
				if(s[i]==j)continue;//当前位置与原来位置的数相同就跳过
				string tem=s;
				tem[i]=j;//改变一位数字
				int x=stoi(tem);
				if(st[x]||d[x]!=-1)continue;//如果改变后的数不是质数,或者已经被搜索过,就跳过该数
				d[x]=d[t]+1;//更新最短距离
				
				q.push(x);
			
		
	


int main()

	getprime(N);
	
	int T;
	cin>>T;
	while(T--)
	
		int a,b;
		cin>>a>>b;
		bfs(a);
		if(d[b]==-1)puts("Impossible");
		else cout<<d[b]<<endl;
	
	
	return 0;

POJ3126 Prime Path bfs, 水题 难度:0

题目

http://poj.org/problem?id=3126


题意

多组数据,每组数据有一个起点四位数s, 要变为终点四位数e, 此处s和e都是大于1000的质数,现在要找一个最短的路径把s变为e,每步可以做如下操作,把当前的s中的四位数上的某一位改变,比如1009可以变为2009,1008,1309,1049,然后检验结果是否为大于1000的质数,如果是,那就可以把s变为这个数。

思路

质数明显需要先处理出来,然后采用bfs获取结果即可。

感想

下次需要先计算空间复杂度, 1e8的空间复杂度肯定会MLE

代码

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int maxn = 10000;

bool p[maxn];
int ans[maxn];
int b[9 * 4], num;

void calPrime()
{
    p[2] = true;
    for(int i = 3; i < maxn; i += 2)p[i] = true;
    for(int i = 3; i < maxn; i += 2)
    {
        if(p[i])
        {
            for(int j = 3; j * i < maxn; j+= 2)
            {
                p[i * j] = false;
            }
        }
    }
}

void getSameShape(int s)
{
    num = 0;
    for(int base = 1; base < maxn; base *= 10)
    {
        int t = s - ((s % (base * 10)) / base) * base;
        for(int i = 0; i < 10; i++)
        {
            int tmp = t + i * base;
            if(tmp > 1000 && p[tmp] && tmp != s)
            {
                b[num++] = tmp;
            }
        }
    }
}

void calAns(int s, int e)
{
    memset(ans, -1, sizeof ans);
    if(!p[s])return;
    ans[s] = 0;
    queue<int> que;
    que.push(s);
    while(!que.empty())
    {
        s = que.front();
        que.pop();
        getSameShape(s);
        for(int j = 0; j < num; j++)
        {
            if(ans[b[j]] == -1)
            {
                ans[b[j]] = ans[s] + 1;
                if(e == b[j])return;
                que.push(b[j]);
            }
        }

    }
}

int main()
{
#ifdef LOCAL
    freopen("input.txt","r",stdin);
#endif // LOCAL
    int n, m;
    int T;
    calPrime();
    scanf("%d",&T);
    for(int ti = 0; ti < T && scanf("%d%d", &n, &m) == 2; ti++)
    {
        calAns(n, m);
        if(ans[m] != -1)printf("%d\n",ans[m]);
        else puts("Impossible");
    }
    return 0;
}

 

以上是关于6.质数路径(简单搜索 BFS)的主要内容,如果未能解决你的问题,请参考以下文章

poj3984 迷宫问题(简单的输出路径的bfs)

深度优先搜索DFS和广度优先搜索BFS

POJ3126 Prime Path bfs, 水题 难度:0

搜索(BFS)---最短单词路径

广度优先(bfs)和深度优先搜索(dfs)的应用实例

使用BFS(广度优先搜索)解迷宫类问题