POJ3126 Prime Path 四维BFS

题目大意:给你两个4位素数A和B,让你把A经过若干次修改后变为B,每次修改只能修改A中的一个数字且修改后的数要仍为素数,且修改的过程中不能出现重复的素数。问你素数A变为素数B最少需要经过几次修改。如果不存在一系列的修改使A变为B,输出Impossible。


分析:四维BFS。我们把每一个数子对应为一个四维数组,那么问题就变为了在一个四维空间中,由起始点(素数A)到终点(素数B)的最短距离了,然后打一个4位数的素数表来作为可移动的空间。需要注意的是每个点可以在其移动方向上走不固定的步数,拿素数1033来说吧,他对应于坐标cnt[1][0][3][3],我们在搜索时,让第一维坐标在0到9的范围内进行搜索,发现其对应的9个数都不是素数,接下来搜索第二维,发现1733是素数,然后把这个数作为第一个修改数。以此类推,直至搜索结束。


实现代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int dir[8][4]={{-1,0,0,0},{1,0,0,0},{0,-1,0,0},{0,1,0,0},{0,0,-1,0},{0,0,1,0},{0,0,0,-1},{0,0,0,1}};
bool prime[10001];
int ea,eb,ec,ed;
typedef struct nod
{
    int a,b,c,d;
    int w;
}node;
void is_prime()
{
    int i,j;
    memset(prime,true,sizeof(prime));
    for(i=2;i<=10000;i++)
      for(j=i*i;j<=10000;j+=i)
        prime[j]=false;
    for(i=1;i<1000;i++)
      prime[i]=false;
}
void bfs(int a,int b,int c,int d)
{
    node que[10005];
    bool s[11][11][11][11]={0};
    int cmp1=1,cmp2=1;
    que[cmp1].a=a;
    que[cmp1].b=b;
    que[cmp1].c=c;
    que[cmp1].d=d;
    que[cmp1].w=0;
    s[a][b][c][d]=1;
    while(cmp1<=cmp2&&!s[ea][eb][ec][ed])
    {
        for(int i=0;i<8;i++)
        {
            node cnt=que[cmp1];
            int ca=cnt.a;
            int cb=cnt.b;
            int cc=cnt.c;
            int cd=cnt.d;
            while(true)
            {
                ca+=dir[i][0];
                cb+=dir[i][1];
                cc+=dir[i][2];
                cd+=dir[i][3];
                if(ca<1||ca>9||cb<0||cb>9||cc<0||cc>9||cd<0||cd>9) break;
                if(prime[ca*1000+cb*100+cc*10+cd]&&!s[ca][cb][cc][cd])
                {
                    cmp2++;
                    s[ca][cb][cc][cd]=1;
                    que[cmp2].a=ca;
                    que[cmp2].b=cb;
                    que[cmp2].c=cc;
                    que[cmp2].d=cd;
                    que[cmp2].w=que[cmp1].w+1;
                    continue;
                }
            }
        }
        cmp1++;
    }
    if(cmp1>cmp2) puts("Impossible");
    else printf("%d\n",que[cmp2].w);
}
int main()
{
    is_prime();
    int start,end;
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%d%d",&start,&end);
        ea=end/1000;
        eb=(end/100)%10;
        ec=(end/10)%10;
        ed=end%10;
        bfs(start/1000,(start/100)%10,(start/10)%10,start%10);
    }
    return 0;
}


你可能感兴趣的:(POJ3126 Prime Path 四维BFS)