1. 程式人生 > >POJ-3126 Prime Path 【BFS+剪枝】

POJ-3126 Prime Path 【BFS+剪枝】

題目傳送門

題目:給定兩個四位數n,m,每次改變n中的一位數並且保證改變後的n仍然是素數,問n最少要經過多少次改變才能變成m。若不論經過多少次改變都不能變成m那麼輸出Impossible。

題解:BFS,列舉改變的數。

注意:1.最後一位數一定不能是偶數,中間兩位數可以是0~9的任意值,第一位數一定不能是0。

           2.如果一個改變的數在之前就已經得到過了,就不用再次變回它了,所以用vis陣列標記一下已經改變過的數。

AC程式碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
using namespace std;
#define io ios::sync_with_stdio(0),cin.tie(0)
#define ms(arr) memset(arr,0,sizeof(arr))
#define inf 0x3f3f3f
typedef long long ll;
const int mod=1e9+7;
const int maxn=1e5+7;
int t,n,m,vis[maxn];
struct node
{
    int a,b,c,d;
    int step;
    node(){}
    node(int _a,int _b,int _c,int _d):a(_a),b(_b),c(_c),d(_d){}
};
bool isPrime(int x)//判斷x是否為素數
{
    for(int i=2;i*i<=x;i++)
    {
        if(x%i==0)
            return false;
    }
    return true;
}
bool isequal(node x,node y)//判斷x,y是否相等
{
    if(x.a==y.a&&x.b==y.b&&x.c==y.c&&x.d==y.d)
        return true;
    return false;
}
queue <node> q;
void bfs()
{
    while(!q.empty())
    {
        q.pop();
    }
    vis[n]=1;
    node tmp;
    tmp.a=n%10;n/=10;
    tmp.b=n%10;n/=10;
    tmp.c=n%10;n/=10;
    tmp.d=n;
    tmp.step=0;
    node ans;
    ans.a=m%10;m/=10;
    ans.b=m%10;m/=10;
    ans.c=m%10;m/=10;
    ans.d=m;
    q.push(tmp);
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        if(isequal(now,ans))//若now與ans相等,輸出now改變的次數
        {
            cout<<now.step<<endl;
            return ;
        }
        for(int i=1;i<=9;i+=2)
        {
            if(now.a!=i)
            {
                tmp=node(i,now.b,now.c,now.d);
                tmp.step=now.step+1;
                if(isPrime(tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000)&&vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]==0)
                {
                    q.push(tmp);
                    vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]=1;
                }
            }
        }
        for(int i=0;i<=9;i++)
        {
            if(now.b!=i)
            {
                tmp=node(now.a,i,now.c,now.d);
                tmp.step=now.step+1;
                if(isPrime(tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000)&&vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]==0)
                {
                    q.push(tmp);
                    vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]=1;
                }
            }
        }
        for(int i=0;i<=9;i++)
        {
            if(now.c!=i)
            {
                tmp=node(now.a,now.b,i,now.d);
                tmp.step=now.step+1;
                if(isPrime(tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000)&&vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]==0)
                {
                    q.push(tmp);
                    vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]=1;
                }
            }
        }
        for(int i=1;i<=9;i++)
        {
            if(now.d!=i)
            {
                tmp=node(now.a,now.b,now.c,i);
                tmp.step=now.step+1;
                if(isPrime(tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000)&&vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]==0)
                {
                    q.push(tmp);
                    vis[tmp.a+tmp.b*10+tmp.c*100+tmp.d*1000]=1;
                }
            }
        }
    }
    cout<<"Impossible"<<endl;
    return ;
}
int main()
{
    io;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        ms(vis);
        bfs();
    }
    return 0;
}