1 条题解

  • 0
    @ 2025-6-16 16:12:19
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    using namespace std;
    
    #define MAX 10000
    bool prime[MAX];
    
    // 优化的素数打表函数
    void init() {
        // 初始化所有数为素数
        memset(prime, true, sizeof(prime));
        prime[0] = prime[1] = false;
        
        // 埃拉托斯特尼筛法优化版
        for (int i = 2; i * i < MAX; i++) {
            if (prime[i]) {
                for (int j = i * i; j < MAX; j += i) {
                    prime[j] = false;
                }
            }
        }
    }
    
    int bfs(int first, int last) {
        bool dis[MAX];
        queue<int> q;
        int count1[MAX];
        
        // 初始化距离数组和访问数组
        memset(dis, false, sizeof(dis));
        memset(count1, 0, sizeof(count1));
        
        q.push(first);
        dis[first] = true;
        
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            
            // 提前退出:如果当前就是目标数
            if (v == last) {
                return count1[v];
            }
            
            // 分解四位数字
            int t[4];
            t[0] = v / 1000;
            t[1] = v % 1000 / 100;
            t[2] = v % 100 / 10;
            t[3] = v % 10;
            
            for (int j = 0; j < 4; j++) {
                int temp = t[j];
                for (int i = 0; i < 10; i++) {
                    if (i != temp) {
                        t[j] = i;
                        int vtemp = t[0] * 1000 + t[1] * 100 + t[2] * 10 + t[3];
                        
                        // 检查是否是有效四位素数且未访问过
                        if (vtemp >= 1000 && !dis[vtemp] && prime[vtemp]) {
                            count1[vtemp] = count1[v] + 1;
                            dis[vtemp] = true;
                            q.push(vtemp);
                            
                            // 找到目标时立即返回
                            if (vtemp == last) {
                                return count1[vtemp];
                            }
                        }
                    }
                }
                t[j] = temp; // 还原数字
            }
        }
        
        return -1; // 无法到达
    }
    
    int main() {
        int st, ed, n;
        init(); // 初始化素数表
        
        cin >> n;
        while (n--) {
            cin >> st >> ed;
            int ans = bfs(st, ed);
            if (ans != -1) {
                cout << ans << endl;
            } else {
                cout << "Impossible" << endl;
            }
        }
        return 0;
    }
    这个问题本质上是一个图搜索问题,我们需要找到从一个四位素数到另一个四位素数的最短路径,每次只能改变一个数字且每次改变后必须仍然是素数。最适合的解决方案是使用广度优先搜索 (BFS),因为 BFS 能保证找到最短路径。
    
    首先,我们需要解决两个关键问题:
    
    如何高效判断四位数字是否为素数
    如何使用 BFS 找到最短转换路径
    • 1

    信息

    ID
    2127
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者