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;
}
本文来自博客园,作者:风雨zzm,转载请注明原文链接:https://www.cnblogs.com/zzmxj/p/17367260.html