POJ 3126 - Prime Path - [線性篩+BFS]

題目連接:http://poj.org/problem?id=3126spa

 

題意:code

給定兩個四位素數 $a,b$,要求把 $a$ 變換到 $b$。變換的過程每次只能改動一個數,要保證每次變換出來的數都是一個沒有前導零的四位素數。blog

要求每步獲得的素數都不能重複,求從 $a$ 到 $b$ 最少須要變換多少步;若是沒法達到則輸出Impossible。隊列

 

題解:get

在BFS以前先用線性篩篩出 $10000$ 之內的素數,方便後面判斷是否爲素數。string

剩下的就是從 $a$ 爲起點,入隊並標記已經出現過。每次隊列非空就取出隊頭,嘗試把這個數的每一位所有改一編,是素數且沒出現過的就入隊並標記。it

循環往復,直到到達 $b$;或者隊列空了還沒找到。io

 

AC代碼:class

#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);
    }
}
相關文章
相關標籤/搜索