POJ3126-Prime Path(BFS)

版权声明:版权归Ordinarv所有 https://blog.csdn.net/ordinarv/article/details/82180226

题目大意

给两个素数a、b,要求每次只能改变一个数字并且最高位不能为0,而且每次变换后的数字也要为素数,求最少改几次能由a得到b。


分析

显然,打素数表,BFS即可。

具体为,4位数字,每次改变一位从0-9替换,判断是否满足,入队,直到==b

注意,不要忘记a==b时,替换后,要在复原回去。


AC Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e4+10;
using namespace std;

bool prime[maxn],vis[maxn];
int a,b,cnt[maxn];
void isprime() {
	prime[0] = prime[1] = false;
	for(int i = 2 ; i < maxn ; i ++) prime[i] = true;
	for(int i = 2 ; i*i <= maxn ; i ++) {
		if(!prime[i]) continue;
		for(int j = i*2 ; j < maxn ; j += i) {
			prime[j] = false;
		}
	}
}

int bfs() {
	memset(cnt,0,sizeof(cnt));
	if(a==b)return cnt[a];
	queue<int> q;	
	memset(vis,0,sizeof(vis));
	int t[4],cur,next,tem;
	q.push(a);
	vis[a]=1;
	int cas=1;
	while(!q.empty()) {
		cur=q.front();
		q.pop();
		t[0]=cur/1000;
		t[1]=cur/100%10;
		t[2]=cur/10%10;
		t[3]=cur%10;
		//printf("%d %d %d %d\n",t[0],t[1],t[2],t[3]);
		for(int i=0; i<4; i++) {
			tem=t[i];
			for(int j=0; j<10; j++) { //use j <->t[i];
				if(t[i]==j||(i==0&&j==0)) continue;
				t[i]=j;
				next=t[0]*1000+t[1]*100+t[2]*10+t[3];
				if(prime[next]&&!vis[next]) { 
 					cnt[next]=cnt[cur]+1;
 					vis[next]=1;
 					q.push(next);
				}
				if(next==b) return cnt[next];
			}
			t[i]=tem;
		}		
	}
	return -1;
}

int main() {
	isprime();
	int t;
	scanf("%d",&t);
	while(t--) {
		scanf("%d%d",&a,&b);		
		printf("%d\n",bfs());
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ordinarv/article/details/82180226