Prime Path POJ-3126

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

  题目大意:n组输入,每一组输入两个四位质数,对第一个质数进行转换,使之变为第二个质数,每次只能更改一个数中某一位的数,且变动一位后的数也是质数才符合要求。输出最少经过几次转换,能转换成第二个质数,保证输入合法。  思路:我这里采用了比较笨的方法,用结构体存储每一位上的数,以及总数,建立结构体队列,进行广度优先搜索,通过数组存储转换次数信息。(主要是自己比较菜,获取某个数中每一位的数不够熟练,后续会补上用整型解决问题的思路。)还有一个问题是判断某数是否为质数的函数,这里我参考了大佬的博客(https://blog.csdn.net/huang_miao_xin/article/details/51331710),很巧妙的判断质数的算法,值得学习。代码如下:
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#include <string.h>
int const max_n = 10002;
using namespace std;
int jug[max_n];//记录信息数组
struct node {
    int a, b, c, d;//千位,百位,十位,个位
    int sum;//数的大小
};
queue<node> q;
int test(node x)//由各个数位的数求大小
{
    return x.a * 1000 + x.b * 100 + x.c * 10 + x.d;
}
bool judge(int x)//是否为质数
{//关于这种方法判断质数的解释,6x,6x+2,6x+4一定被2整除,6x+3一定被3整除,这样就只用判断6x+1和6x+5的数了。而当循环以6位单位跨进时,就是6x-1和6x+1的情况了。更详细的讲解可以去大佬博客看
    if (x == 2 || x == 3)return true;//特判2,3两个质数
    if (x % 6 != 1 && x % 6 != 5)return false;
    int tmp = sqrt(x);
    for (int i = 5; i <= tmp; i += 6)
    {
        if (x%i == 0 || x % (i + 2) == 0)return false;
    }
    return true;
}
int bfs(int x, int y)
{
    node sx;
    sx.a = x / 1000;
    sx.b = x / 100 % 10;
    sx.c = x / 10 % 10 % 10;
    sx.d = x % 1000 % 100 % 10;
    sx.sum = x;
    q.push(sx);//入队
    memset(jug, 0, sizeof(jug));
    jug[x] = 1;
    while (!q.empty())
    {
        node s = q.front(); q.pop();
        if (s.sum == y)return jug[s.sum] - 1;
        for (int i = 1; i < 10; i++)//千位进行转换
        {
            node p;
            p.a = s.a, p.b = s.b, p.c = s.c, p.d = s.d;
            p.a = i;
            p.sum = test(p);
            if (judge(p.sum) && jug[p.sum] == 0)
            {
                jug[p.sum] = jug[s.sum] + 1;
                q.push(p);
            }
        }
        for (int i = 0; i < 10; i++)//百位进行转换
        {
            node p;
            p.a = s.a, p.b = s.b, p.c = s.c, p.d = s.d;
            p.b = i;
            p.sum = test(p);
            if (judge(p.sum) && jug[p.sum] == 0)
            {
                jug[p.sum] = jug[s.sum] + 1;
                q.push(p);
            }
        }
        for (int i = 0; i < 10; i++)//十位进行转换
        {
            node p;
            p.a = s.a, p.b = s.b, p.c = s.c, p.d = s.d;
            p.c = i;
            p.sum = test(p);
            if (judge(p.sum) && jug[p.sum] == 0)
            {
                jug[p.sum] = jug[s.sum] + 1;
                q.push(p);
            }
        }
        for (int i = 0; i < 10; i++)//个位进行转换
        {
            node p;
            p.a = s.a, p.b = s.b, p.c = s.c, p.d = s.d;
            p.d = i;
            p.sum = test(p);
            if (judge(p.sum) && jug[p.sum] == 0)
            {
                jug[p.sum] = jug[s.sum] + 1;
                q.push(p);
            }

        }
    }
    return 0;
}
int main()
{
    int t; scanf("%d", &t);
    while (t--)
    {
        int m, n;
        scanf("%d %d", &m, &n);
        while (q.size())q.pop();
        if (m == n) { printf("0\n"); continue; }
        else
        {
            int x = bfs(m, n);
            if (x == 0)printf("Impossible\n");
            else printf("%d\n", x);
        }
    }
    return 0;
}
 

原文地址:https://www.cnblogs.com/whocarethat/p/11099777.html

时间: 2024-10-12 16:52:51

Prime Path POJ-3126的相关文章

F - Prime Path POJ 3126 筛选素数+bfs

F - Prime Path Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3126 Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have t

Prime Path POJ - 3126(简单广搜)

题目链接:https://cn.vjudge.net/problem/POJ-3126 注意:预处理1000-9999间的素数,并且对入过队列的数进行标记,防止重复入队,否则超时 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 #include <algorithm> 6 #include <cmath> 7 #de

20200202 POJ - 3126 Prime Path POJ - 1426 Find The Multiple

>>>>>>>>>POJ 1426直达?? >>>>>>>>>POJ 3126直达?? 做了这么几道搜索题,感觉差不多也摸出了门路,模板差不多记下来了,只是面对不同的题目算法不同罢了 简单写一下想法,搞明白搜索的主题到底是什么(之前的mutiple那题,一开始就没想明白到底搜谁,就没想到算法 TBC(晚上再写 ===================================分割线=======

POJ - 3126 - Prime Path(BFS)

Prime Path POJ - 3126 题意: 给出两个四位素数 a , b.然后从a开始,每次可以改变四位中的一位数字,变成 c,c 可以接着变,直到变成b为止.要求 c 必须是素数.求变换次数的最小值.(a,b,c都是四位数字,输入时没有前导零) 分析: 每次改变可以获得一个四位数c,然后如果c是素数并且之前没有出现过,那么我们把它放入队列即可. int f[10001]; int v[10001]; void init()//素数筛 { memset(f,0,sizeof f); fo

双向广搜 POJ 3126 Prime Path

POJ 3126  Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16204   Accepted: 9153 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 th

POJ 3126 Prime Path(素数路径)

p.MsoNormal { margin-bottom: 10.0000pt; font-family: Tahoma; font-size: 11.0000pt } h1 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: left; font-family: 宋体; font-weight: bold; font-size: 24.0000pt } span.10 { font-family: "Times New Rom

POJ 3126 Prime Path SPFA

http://poj.org/problem?id=3126 题目大意: 给你两个四位的素数s和t,要求每次改变一个数字,使得改变后的数字也为素数,求s变化到t的最少变化次数. 思路: 首先求出所有4位素数. 对于两个素数之间,如果只相差一个数字,那么就建立图,(双向) 最后求最短路即可(可以SPFA也可以BFS) #include<cstdio> #include<cstring> #include<queue> #include<algorithm> u

poj 3126 Prime Path 【暴力BFS】

题意:给你一个4位数,再给你一个4位数,如前一个数的每次只移动一位,问你能不能将第一个数变成第二个. 转移条件:1,只能通过素数作为中转,2,每次移动一位. 如果找到输出最少的转移次数(或步数), 如果找不到输出Impossible. 策略:如题. 直接上代码: #include<stdio.h> #include<string.h> #include<queue> #define M 10005 using std::queue; int vis[10000]; in

(简单) POJ 3126 Prime Path,BFS。

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

poj 3126 Prime Path (bfs)

Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13813   Accepted: 7796 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-dig