POJ-3126

题目链接:vjudge.net/problem/POJ... 题目大意:将一个4位正整数质数,每次改动一位数字,转为另一个四位正整数质数,并且每次改变玩的数字也是质数,找到最小改动次数,可能找不到。

最短路径问题,考虑BFS,做一个质数表,然后四位数,依次枚举即可

枚举过程: 用双循环,第一层枚举4个数位,第二层枚举0-9,把4个数位先分离出来,然后枚举,再还原回去。

易踩坑: memsetmemset(ptr, value, size) 的第二个参数 value 虽然是 int,但它只取低 8 位(一个字节) ,然后把内存的每个字节都设成这个值。 所以如果我的质数表是int prime10000 就会导致,设置出来的结果是16843009,如果我的质数表是bool prime10000,就正常了,因为bool只有一个字节,设置成0x01正好。

AC代码:

c++ 复制代码
#include <algorithm>
#include <iostream>
#include <set>
#include <vector>

#include <unordered_map>
#include <queue>
#include <cstring>

using namespace std;

bool prime[10000];

void set_prime() {
    memset(prime, true, sizeof(prime));
    prime[0] = false;
    prime[1] = false;

    for (int i = 2; i < 10000; i++) {
        if (prime[i] == 1) {
            for (int j = i + i; j < 10000; j += i) {
                prime[j] = 0;
            }
        }
    }
}

int dist[10000];

int bfs(int start, int end) {
    // 一共4位数,个位在1,3,5,7,9中间找 因为4位数质数的个位不可能是0,2,4,5,6,8
    // 十位在 0到 9中间
    // 百位在 0 ~ 9 中间
    // 千位在1 ~ 9中间找

    if (start == end) {
        return 0;
    }

    memset(dist, -1, sizeof(dist));
    queue<int> q;
    q.push(start);
    dist[start] = 0;
    int pow10[4] = {1000, 100, 10, 1};
    while (!q.empty()) {
        int cur = q.front();
        q.pop();
        if (cur == end) {
            return dist[cur];
        }
        int d[4];
        d[0] = cur / 1000;
        d[1] = cur / 100 % 10;
        d[2] = cur / 10 % 10;
        d[3] = cur % 10;
        // 枚举4个数位
        for (int i = 0; i < 4; i++) {
            int old = d[i];
            for (int j = 0; j <= 9; j++) {
                if (j == old) {
                    continue;
                }
                if (i == 0 && j == 0) {
                    continue;
                }
                if (i == 3 && (j % 2 == 0 || j == 5)) {
                    continue;
                }
                int next = cur + (j - old) * pow10[i];
                if (next < 1000 || next > 9999) {
                    continue;
                }
                if (prime[next] && dist[next] == -1) {
                    dist[next] = dist[cur] + 1;
                    q.push(next);
                }
            }
        }
    }
    return -1;
}

int main() {
    set_prime();
    // for (int i = 0; i < 100; i++) {
    //     cout << i << ":" << prime[i] << endl;
    // }
    int n;
    cin >> n;
    while (n--) {
        int start, end;
        cin >> start >> end;
        int ans = bfs(start, end);
        if (ans == -1) {
            cout << "Impossible" << endl;
        } else {
            cout << ans << endl;
        }
    }
}
相关推荐
suhan1 小时前
【数据结构】五、树:6.平衡二叉树AVL
数据结构·算法·排序算法
suhan1 小时前
【数据结构】五、树:5.二叉排序树BST
数据结构·算法·排序算法
爱读书的小胖1 小时前
80. 删除有序数组中的重复项 II
java·数据结构·算法
臻选云栗子2 小时前
PCDN跑不起来?先别甩锅给平台,问题可能出在这
算法·程序员
小画家~2 小时前
vue3 里面的 itemList.reduce
前端·数据结构·算法
All for pursuit.2 小时前
【完结】LeetCodeHot100题 详细解题过程及代码汇总
数据结构·c++·算法·leetcode
重生之小比特3 小时前
【算法拾光】双指针|移动零 + 复写零
数据结构·c++·算法
梦帮科技3 小时前
Linux 内存取证学与 Rootkit 猎杀——Volatility 核心剖析与内核隐藏模块逆向清除
linux·运维·服务器·神经网络·算法·网络安全
广州智造3 小时前
Radioss二次开发需要准备什么?
人工智能·算法·机器学习·cad·cae