1. 程式人生 > >POJ3126-Prime Path(BFS)

POJ3126-Prime Path(BFS)

題目大意

給兩個素數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;
}