poj 3126 Prime Path(BFS)

本文介绍了一个算法问题,即寻找两个四位素数之间的最短转换路径,每次转换仅改变一位数字且保持素数特性。通过BFS算法实现解决方案,并提供源代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Prime Path
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 12421 Accepted: 7031

Description

The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. 
— It is a matter of security to change such things every now and then, to keep the enemy in the dark. 
— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know! 
— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door. 
— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime! 
— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds. 
— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime. 

Now, the minister of finance, who had been eavesdropping, intervened. 
— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound. 
— Hmm, in that case I need a computer program to minimize the cost. You don't know some very cheap software gurus, do you? 
— In fact, I do. You see, there is this programming contest going on... Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above. 
1033
1733
3733
3739
3779
8779
8179
The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.

Input

One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).

Output

One line for each case, either with a number stating the minimal cost or containing the word Impossible.

Sample Input

3
1033 8179
1373 8017
1033 1033

Sample Output

6
7
0

Source

Northwestern Europe 2006




大致题意:

给定两个四位素数a,b,要求把a变换到b

变换的过程要保证每次变换出来的数都是一个四位素数,而且当前这步的变换所得的素数与前一步得到的素数只能有一个位不同,而且每步得到的素数都不能重复。

 

求从ab最少需要的变换次数。无法变换则输出Impossible



  • Source Code
    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    using namespace std;
    
    struct node
    {
        int x;
        int cnt;
    }q1[90000001];
    
    int v[100001];
    const int Max = 1000001;
    bool flag[Max];
    int prime[Max],pi;
    int s,e;
    
    void saixuan()
    {
        int i,j;
        pi = 0;
        memset(flag,0,sizeof(flag));
        for(i=2;i<Max;i++)
        {
            if(flag[i] == 0)
            {
                prime[pi++] = i;
            }
            for(j=0;(j<pi) && (i*prime[j]<Max);j++)
            {
                flag[i*prime[j]] = 1;
                if(i%prime[j] == 0)
                {
                    break;
                }
            }
        }
    }
    
    void BFS(int n,int m)
    {
        struct node t,f;
        t.x = n;
        t.cnt = 0;
        q1[e++] = t;
        v[t.x] = 1;
        while(s<e)
        {
            t = q1[s++];
            if(t.x == m)
            {
                printf("%d\n",t.cnt);
                return ;
            }
            int t1,t2,t3,t4;
            t1 = t.x/1000;
            t2 = t.x/100 - t1*10;
            t3 = t.x/10 - t1*100  - t2*10;
            t4 = t.x%10;
           // printf("t1 = %d   t2 = %d   t3 = %d   t4 = %d    t.cnt = %d   flag[%d] = %d\n",t1,t2,t3,t4,t.cnt,t.x,flag[t.x]);
            for(int i=1;i<10;i++)
            {
                int h = i*1000 + t2*100 + t3*10 + t4;
                if(v[h] == 0 && flag[h] == 0)
                {
                    if(h == m)
                    {
                        f.cnt = t.cnt + 1;
                        printf("%d\n",f.cnt);
                        return ;
                    }
                    f.x = h;
                    f.cnt = t.cnt + 1;
                    q1[e++] = f;
                    v[h] = 1;
                }
            }
            for(int i=0;i<=9;i++)
            {
                int h1 = t1 * 1000 + i * 100 + t3 * 10 + t4;
                int h2 = t1 * 1000 + t2 * 100 + i * 10 + t4;
                int h3 = t1 * 1000 + t2 * 100 + t3 * 10 + i;
                if(v[h1] == 0 && flag[h1] == 0)
                {
                    f.x = h1;
                    f.cnt = t.cnt + 1;
                    q1[e++] = f;
                    v[h1] = 1;
                    if(h1 == m)
                    {
                        f.cnt = t.cnt + 1;
                        printf("%d\n",f.cnt);
                        return ;
                    }
                }
                if(v[h2] == 0 && flag[h2] == 0)
                {
                    f.x = h2;
                    f.cnt = t.cnt + 1;
                    q1[e++] = f;
                    v[h2] = 1;
                    if(h2 == m)
                    {
                        f.cnt = t.cnt + 1;
                        printf("%d\n",f.cnt);
                        return ;
                    }
                }
                if(v[h3] == 0 && flag[h3] == 0)
                {
                    if(h3 == m)
                    {
                        f.cnt = t.cnt + 1;
                        printf("%d\n",f.cnt);
                        return ;
                    }
                    f.x = h3;
                    f.cnt = t.cnt + 1;
                    q1[e++] = f;
                    v[h3] = 1;
                }
            }
        }
    }
    
    int main()
    {
        int n,m;
        int T;
        saixuan();
        scanf("%d",&T);
        while(T--)
        {
            s = 0;
            e = 0;
            scanf("%d%d",&n,&m);
            memset(v,0,sizeof(v));
            BFS(n,m);
        }
        return 0;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶孤心丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值