Prime Path (bfs)

首相们对安全局长带来的消息感到非常不安,他们说他们将为了安全考虑改变首相房间门牌号上面的门牌号码。
 要不时地改变门牌号,这样可以使敌人处于迷惑之中。
但是,我现在的门牌号是1033号,它是一个质数,我有质数强迫症。我不能忍受我的门牌号不是质数。
我知道,所以你的新门牌号8179号也是一个质数。你只需在你办公室的门上更换掉原来的四个数字就可以。
不,不是那么简单。假设我把第一个数字先改为8,那么在你更改下一个数字之前他将是8033,它不是素数!
我明白了,首相,即使在几秒钟内,你也不能忍受一个非质数。
是的!因此,你必须提出一种从1033改为8179而且中间全是质数的方案,每次只可以改变其中一个数位上的数字。

例如:
1033
1733
3733
3739
3779
8779
8179
此时,我们一共更改了6次数字,已知更改一次数字需要花费1英镑,因此我们需要花费6英镑。

你的任务就是写一个程序,对于任意的起始和终止数字,都求出最小花费。
Input
输入数据有多组,首先是一个数字n,代表之后有n组数据。
其次,在每一组输入中,都包含两个数字m和n,m代表原来的门牌号,n代表现在的门牌号。
其中,m和n都是四位数,而且不含前导0。
Output
每组输入输出一行,输出在此情况下的最小花费。
若不存在从m到n的路径,则输出单词“Impossible”。
Sample Input
3
1033 8179
1373 8017
1033 1033
Sample Output
6
7
0
本来不知到怎么做,后来想到了bfs的写法,中间刚开始以为不用标记就行了,结果没有运行结果 (其实是运行中,一直运行中......后来结果是一样的。但是没标记,导致进过队列的数重复进入, 做了很多无用功,后来标记上数组开的太小一直是只有第一组数据对。。。。白白用了俩小时
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int aa1,bb1,cc1,dd1,aa2,bb2,cc2,dd2;
int n,m,ans;
int vis[10000];
struct node
{
    int a;
    int b;
    int c;
    int d;
    int s;
};
int sum(int as,int bs,int cs,int ds)
{
    int sp=as*1000+bs*100+cs*10+ds;
    return sp;
}
int judge(int ft)
{
    for(int i=2; i<=sqrt(ft); i++)
    {
        if(ft%i==0)
        {
            return 0;
        }
    }
    return 1;
}

void bfs()
{
    aa2=m/1000;
    bb2=m/100%10;
    cc2=m/10%10;
    dd2=m%10;
    node now,next;
    now.a=n/1000;
    now.b=n/100%10;
    now.c=n/10%10;
    now.d=n%10;
    now.s=0;
    queue<node>q;
    while(!q.empty()) q.pop();
    q.push(now);
    memset(vis,0,sizeof(vis));
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        if(now.a==aa2&&now.b==bb2&&now.c==cc2&&now.d==dd2)
        {
            ans=now.s;
            return;
        }
        for(int j=1; j<=9; j++)
        {
            int st=sum(j,now.b,now.c,now.d);
            if(j!=now.a&&vis[st]==0&&judge(st))
            {
                next.a=j;
                next.b=now.b;
                next.c=now.c;
                next.d=now.d;
                next.s=now.s+1;
                q.push(next);
                vis[st]=1;
            }

        }
        for(int j=0; j<=9; j++)
        {

            int st=sum(now.a,j,now.c,now.d);
            if(j!=now.b&&vis[st]==0&&judge(st))
            {
                next.a=now.a;
                next.b=j;
                next.c=now.c;
                next.d=now.d;
                next.s=now.s+1;
                q.push(next);
                vis[st]=1;
            }
        }
        for(int j=0; j<=9; j++)
        {

            int st=sum(now.a,now.b,j,now.d);
            if(j!=now.c&&vis[st]==0&&judge(st))
            {
                next.a=now.a;
                next.b=now.b;
                next.c=j;
                next.d=now.d;
                next.s=now.s+1;
                q.push(next);
                vis[st]=1;
            }
        }
        for(int j=1; j<=9; j++)
        {

            int st=sum(now.a,now.b,now.c,j);
            if(j!=now.d&&vis[st]==0&&judge(st))
            {
                next.a=now.a;
                next.b=now.b;
                next.c=now.c;
                next.d=j;
                next.s=now.s+1;
                q.push(next);
                vis[st]=1;
            }
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ans=-1;
        scanf("%d%d",&n,&m);
        bfs();
       if(ans!=-1) printf("%d\n",ans);
       else printf("Impossible\n");
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值