Prime Path

Description

内阁的部长们对于安全部门首脑声称要改变他们办公室的4个房间号非常烦恼。
—这只是一件安全措置,不时地改变这样的事物,使得敌人处于盲区。
— 但是你看,我已经选了我的房间号1033有很好的理由,我是总理,你知道的。
— 我知道的,所以你的新房间号8179也是素数,你只要在你的办公室房门上将这新的4位数字贴在老的4位数字上就可以了。
— 不,不那么简单。假如我把第一个数字改成8,那么数字8033就不是素数!
— 我知道,作为总理,你不能忍受一个非素数作为你的房间号即使只有几秒钟。
— 正确!我必须找到一个从1033到8179的一个素数路径的方案,从一个素数到下一个素数只要改变一位数。
一直在听的财政部长,也介入了讨论。
— 请不要产生不必要的开支!我碰巧知道,改一位数字的价格是1英镑。
— 在这种情况下,我需要一个计算机程序使得花费最小化,你知道有非常便宜的软件开发者吗?
— 我知道。有个程序设计竞赛马上要进行了。让他们帮助总理在两个四位素数之间找到最便宜的素数路径。当然,第一位是非零的。上述实例有个解答:
1033
1733
3733
3739
3779
8779
8179
这个解答花费6英镑。注意第1个位置在第2步被粘贴,在最后一步不能被重用,在第1个位置上要粘贴新值必须购买。

 

Input

第一行给出一个正整数:测试用例的数目(最多100)。每个测试用例一行,两个用空格分开的数字,这两个数字都是4位素数(不以0作为首位)。

Output

对于每个测试用例,输出一行,或者是最小花费的数目,或者输出Impossible。

 

Sample Input

3
1033 8179
1373 8017
1033 1033

Sample Output

6
7
0

 

思路:

用bfs实现。

获取队头元素,数位分离,枚举所有可拓展情况,每种情况判断是否为素数,如果是且没有访问过则入队。

当然千位不能是0。

代码: 

#include<iostream>
#include<queue>

using namespace std;
 
struct data
{
    int num,ans;
};

queue<data> q;
int n,start,last,minn=99999999;
bool vis[10001];
 
bool prime(int number)
{
    for(int i=2;i*i<=number;i++)
        if(number%i==0)return false;
    return true;
}
 
int main()
{
    cin>>n;
    for(int k=1;k<=n;k++)
    {
        cin>>start>>last;
        if(start==last)
        {
            cout<<"0"<<endl;
            continue;
        }
        bool flag=false;
        q.push((data){start,0});
        vis[start]=true;
        while(!q.empty())
        {
            data u=q.front();
            q.pop();
            if(u.num==last)
            {
                flag=true;
                minn=min(u.ans,minn);
                continue;
            }
            int di[4];
            di[0]=u.num%10;//个
            di[1]=u.num/10%10;//十
            di[2]=u.num/100%10;//百
            di[3]=u.num/1000;//千
            for(int i=0;i<4;i++)
            {
                for(int j=0;j<=9;j++)
                {
                    if(i==3&&j==0)continue;
                    int temp=di[i];
                    di[i]=j;
                    int number=di[0]+di[1]*10+di[2]*100+di[3]*1000;
                    if(prime(number)&&!vis[number])
                    {
                        q.push((data){number,u.ans+1});
                        vis[number]=true;
                    }
                    di[i]=temp;
                }
            }
        }
        if(flag)cout<<minn<<endl;
        else cout<<"Impossible"<<endl;
        for(int i=1000;i<=9999;i++)
            vis[i]=false;
        minn=99999999;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值