POJ - 3126 Prime 素数筛+最短路

题目简述

给定两个四位数字a和b,通过构建一条最短的质数道路以将a变成b,实现方式为:改动a中一位数字,使其成为一个新的质数,重复此步骤直到新质数为b。

数据范围

样例数 T100

题解

通过埃氏筛预先打表出所有质数,将只有一个数位不同的两个质数(如1033和1733)相互建边,将a作为起点跑一遍最短路即可。

Code

点击查看代码
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define N 10005
#define M 200005
#define inf 0x3f3f3f3f
int prime[N],cnt;
int T,a,b,tot;
bool st[N];// not prime 
bool vis[N];
vector<int> pri; 
int to[M],from[N<<1],val[M],dis[N<<1],nxt[M];
void add(int a,int b,int c){
	to[++tot]=b;
	val[tot]=c;
	nxt[tot]=from[a];
	from[a]=tot;
}
bool judge(int x,int y){
	int check=0;
	while(x){
		if(x%10==y%10) check++;
		x/=10;y/=10; 
	}
	return check==3;
}
void init(){
	for(int i=0;i<pri.size();i++)
		for(int j=i+1;j<pri.size();j++)
			if(judge(pri[i],pri[j])) add(pri[i],pri[j],1),add(pri[j],pri[i],1);
}


priority_queue<pair<int,int> > q;
void dijstra(int s){
	dis[s]=0;
	q.push(make_pair(0,s));
	while(!q.empty()){
		int t=q.top().second;q.pop();
		if(vis[t]) continue;vis[t]=1;
		for(int i=from[t];i;i=nxt[i]){
			if(dis[to[i]]>dis[t]+val[i]){
				dis[to[i]]=dis[t]+val[i];
				q.push(make_pair(-dis[to[i]],to[i]));
			}
		}
	}
}
int ip(){
	int x=0,w=0;char ch=0;
	while(!isdigit(ch)) w|=ch=='-',ch=getchar();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return w?-x:x;
}
int main(){
	T=ip();
	for(int i=2;i*i<=N;i++)
		if(!st[i]) 
			for(int j=i*i;j<=N;j+=i)
				 st[j]=1;
	for(int i=1000;i<=9999;i++)
		if(!st[i])
			pri.push_back(i);
	while(T--){
		a=ip(),b=ip();
		if(a==b){
			puts("0");
			continue;
		}
		init();
		memset(dis,inf,sizeof(dis));
		memset(vis,0,sizeof(vis));
		dijstra(a);
		if(dis[b]!=inf) printf("%d\n",dis[b]);
		else puts("Impossible");
	}
	return 0;
} 
posted @   SxtoxA  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
12 13
点击右上角即可分享
微信分享提示