Prime Path POJ

hh学长酷爱素数,他经常自娱自乐,随机挑选两个四位的素数a,b。
游戏规则是:a可以通过改变某一位上的数字使其变成c,但只有当c也是四位的素数时才能进行这种改变。
hh学长可以很轻松的算出a最少经过多少次变化使其变为b,所以他相信你也可以。
例如:1033 -> 8179
1033
1733
3733
3739
3779
8779
8179
最少变换了6次。

Input
第一行输入整数T,表示样例数。 (T <= 100)
每个样例输入两个四位的素数a,b。(没有前导零)

Output
对于每个样例,输出最少变换次数,如果无法变换成b则输出"Impossible"。

Sample Input
3
1033 8179
1373 8017
1033 1033

Sample Output
6
7
0
预处理出来所有的素数,只有一千多个,可以在任意两个素数之间建一条边,可以经过一次变换边权为1,否则边权为0。
如果a==b那么直接输出0,如果b不是素数输出impossible,其他情况在边权为1之间的边中跑一遍最短路(如果a不是素数还要在a与所有素数之间建一条边)

#include<iostream>
#include<algorithm> 
#include<vector>
#include<cstring>
#include<queue>
#include<cstdio>
#include<map>
using namespace std;
#define pii pair<int,int> 
typedef long long ll;
const int N=10010,M=2000;
int n,p[10];
bool prim[N];
vector<int> res; 
bool g[N][N];//开int会MLE 
bool check(int x,int y)//判断是否可以经过一次变换,用差值判断会错
{
	int cnt=0;
	while(x)
	{
		if(x%10==y%10) cnt++;
		x/=10;y/=10; 
	}
	return cnt==3;
}
void init()
{
	prim[1]=1;
	for(int i=2;i<=N/i;i++)
	{
		if(!prim[i])
			for(int j=i*i;j<N;j+=i)
				prim[j]=1;
	}
	for(int i=1000;i<10000;i++)
		if(!prim[i]) res.push_back(i);
	for(int i=0;i<res.size();i++)//建边
		for(int j=i+1;j<res.size();j++)
				if(check(res[i],res[j])) g[i][j]=g[j][i]=1;
}
int dist[M];
bool vis[M];
void dij(int st,int en)
{
	memset(dist,0x3f,sizeof dist);
	priority_queue<pii,vector<pii>,greater<pii> > q;
	dist[st]=0;
	q.push({0,st});
	memset(vis,0,sizeof vis);
	while(q.size())
	{
		int u=q.top().second;
		q.pop();
		if(u==en) break;
		if(vis[u]) continue;
		for(int i=0;i<res.size();i++)
		{
			if(g[u][i]&&dist[i]>dist[u]+1)
			{
				dist[i]=dist[u]+1;
				q.push({dist[u]+1,i});
			}
		}
		vis[u]=1;
	}
}
int main()
{
	init();
	int t;
	cin>>t;
	while(t--)
	{
		int a,b;
		cin>>a>>b;
		int l=lower_bound(res.begin(),res.end(),a)-res.begin();
		int r=lower_bound(res.begin(),res.end(),b)-res.begin();
		if(a==b) puts("0");
		else if(prim[b]) puts("Impossible");
		else 
		{
			if(prim[a])
			{
				for(int i=0;i<res.size();i++) g[res.size()][i]=(check(a,res[i])?1:0);
				l=res.size();
			}
			dij(l,r);
			if(dist[r]!=0x3f3f3f3f) cout<<dist[r]<<endl;
			else puts("Impossible");
		}
	}
}```

原文地址:https://www.cnblogs.com/neflibata/p/12871738.html