POJ 3126 - Prime Path - [线性筛+BFS]
题目链接:http://poj.org/problem?id=3126
题意:
给定两个四位素数 $a,b$,要求把 $a$ 变换到 $b$。变换的过程每次只能改动一个数,要保证每次变换出来的数都是一个没有前导零的四位素数。
要求每步得到的素数都不能重复,求从 $a$ 到 $b$ 最少需要变换多少步;如果无法达到则输出Impossible。
题解:
在BFS之前先用线性筛筛出 $10000$ 以内的素数,方便后面判断是否为素数。
剩下的就是从 $a$ 为起点,入队并标记已经出现过。每次队列非空就取出队头,尝试把这个数的每一位全部改一编,是素数且没出现过的就入队并标记。
循环往复,直到到达 $b$;或者队列空了还没找到。
AC代码:
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; typedef pair<int,int> pii; int st,ed; /************************** 线性筛 - st **************************/ const int MAX=10000; int cnt,prime[MAX+5]; bool isPrime[MAX+5]; void Screen() //欧拉筛法求素数 { cnt=0; memset(isPrime,1,sizeof(isPrime)); isPrime[0]=isPrime[1]=0; for(int i=2;i<=MAX;i++) { if(isPrime[i]) prime[cnt++]=i; for(int j=0;j<cnt;j++) { if(i*prime[j]>MAX) break; isPrime[i*prime[j]]=0; if(i%prime[j]==0) break; } } } /************************** 线性筛 - ed **************************/ queue<pii> Q; bool vis[MAX+5]; int bfs() { memset(vis,0,sizeof(vis)); while(!Q.empty()) Q.pop(); Q.push(make_pair(st,0)); vis[st]=1; while(!Q.empty()) { pii now=Q.front(); Q.pop(); if(now.first==ed) return now.second; for(int i=1;i<=9;i++) //千位 { int k=now.first/1000; if(k==i) continue; pii nxt=make_pair(now.first-k*1000+i*1000,now.second+1); if(isPrime[nxt.first] && !vis[nxt.first]) { Q.push(nxt); vis[nxt.first]=1; } } for(int i=0;i<=9;i++) //百位 { int k=(now.first%1000)/100; if(k==i) continue; pii nxt=make_pair(now.first-k*100+i*100,now.second+1); if(isPrime[nxt.first] && !vis[nxt.first]) { Q.push(nxt); vis[nxt.first]=1; } } for(int i=0;i<=9;i++) //十位 { int k=(now.first%100)/10; if(k==i) continue; pii nxt=make_pair(now.first-k*10+i*10,now.second+1); if(isPrime[nxt.first] && !vis[nxt.first]) { Q.push(nxt); vis[nxt.first]=1; } } for(int i=0;i<=9;i++) //个位 { int k=now.first%10; if(k==i) continue; pii nxt=make_pair(now.first-k+i,now.second+1); if(isPrime[nxt.first] && !vis[nxt.first]) { Q.push(nxt); vis[nxt.first]=1; } } } return -1; } int main() { Screen(); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&st,&ed); int ans=bfs(); if(ans==-1) printf("Impossible\n"); else printf("%d\n",ans); } }
转载请注明出处:https://dilthey.cnblogs.com/