zoukankan      html  css  js  c++  java
  • POJ 3126 Prime Path

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

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

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

     

    输入:

    第一行 是一个数T 表示下面有T个测试数据

    下面T行  每行两个数a b

    解题思路:每次变换一次,个十百千,四个位置上的数每个从0-9循环一边一共需要4 * 10 = 40次循环  剪枝之后就没多少了 所以直接暴力BFS能过

    下面是代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cstdlib>
    #include <cmath>
    #include <cctype>
    #define N 10000
    #define MAXV 10000
    using namespace std;
    bool Prime[11000];//Prime[i] = false证明 i 是素数
    void MakePrime()//对素数打表
    {
        int i, j;
        for(i = 1000; i <= N; i++) {
            for(j = 2; j < i; j++) {
                if(i % j == 0) {
                    Prime[i] = false;
                    break;
                }
            }
            if(j == i) Prime[i] = true;
        }
    }
    void BFS(int s, int e)
    {
        bool maps[N]; //用来记录此数是不是已经变换过
        int step[N], d[4], temp, e_temp, i, j; //d代表个十百千四个位置,step[i]用来储存变换为 i 时一共变换了几次
        queue<int>q;
        memset(step, 0, sizeof(step));
        memset(maps, false, sizeof(maps));
        q.push(s);
        maps[s] = true;
        while(!q.empty()) {
            s = q.front();
            q.pop();
            d[0] = s % 10;//
            d[1] = s / 10 % 10;//
            d[2] = s / 100 % 10;//
            d[3] = s / 1000;//
            for(i = 0; i < 4; i++) { //四个位置
                temp = d[i]; //原本在此位置的数字 先用temp保存 因为后面如果改变的是其他位置这个位置不变
                for(j = 0; j < 10; j++) { //0-9十个数
                if(temp != j) { //自己不需要再次判断
                    d[i] = j;
                    e_temp = d[0] + d[1] * 10 + d[2] * 100 + d[3] * 1000;
                    if(!maps[e_temp] && Prime[e_temp]) { //判断这个数有没有判断过,是不是质数
                        maps[e_temp] = true;
                        step[e_temp] = step[s] + 1;
                        q.push(e_temp);
                    }
                    if(e_temp == e) { //查找到 输出转换次数
                        printf("%d
    ", step[e_temp]);
                        return;
                    }
                }
                d[i] = temp;
                }
            }
            if(s == e) {
            printf("%d
    ", step[s]);
            return;
            }
        }
    //所有的数都变换过 无法得到结果
       printf("Impossible
    ");
    }
    int main()
    {
        MakePrime();
        int start, end, T;
        scanf("%d", &T);
        while(T--) {
            scanf("%d %d", &start, &end);
            BFS(start, end);
        }
    }
  • 相关阅读:
    coding++:SpringBoot-事务注解详解
    coding++:java-自定义签名+拦截器
    linux++:Linux
    coding++:java-全局异常处理
    POJ 2823 双端队列
    POJ 3250 栈
    10进制数字向0~3999的罗马数字的转换
    POJ 1986 LCA
    POJ 1236 强联通分量
    河南工业大学2017校赛题解
  • 原文地址:https://www.cnblogs.com/wangyuhao/p/4685106.html
Copyright © 2011-2022 走看看