top1编程
← 返回题目
题解

【提高】密码锁

1 条题解

  • 0
    @ 2026-7-29 0:15:35
    #include <iostream>
    #include <vector>
    #include <string>
    #include <cmath>
    #include <climits>
    using namespace std;
    
    const int MAX = 100000;
    vector<bool> is_prime(MAX, true); // 素数标记数组
    
    // 预处理1~99999的素数(埃氏筛)
    void sieve() {
        is_prime[0] = is_prime[1] = false;
        for (int i = 2; i * i < MAX; ++i) {
            if (is_prime[i]) {
                for (int j = i * i; j < MAX; j += i) {
                    is_prime[j] = false;
                }
            }
        }
    }
    
    // 计算初始数字到目标素数的总拨动次数
    int calc_cost(const string& init, int prime) {
        // 将素数转为5位字符串(补前导0)
        string target = to_string(prime);
        while (target.size() < 5) {
            target = "0" + target;
        }
        
        int total = 0;
        for (int i = 0; i < 5; ++i) {
            int a = init[i] - '0';
            int b = target[i] - '0';
            int diff = abs(a - b);
            total += min(diff, 10 - diff); // 最小拨动次数
        }
        return total;
    }
    
    int main() {
        sieve(); // 预处理素数
        
        string init;
        cin >> init; // 输入5位初始数字(如01212)
        
        int min_cost = INT_MAX;
        int best_prime = -1;
        
        // 遍历所有5位素数(10000~99999)
        for (int p = 10000; p < 100000; ++p) {
            if (!is_prime[p]) continue;
            
            int cost = calc_cost(init, p);
            // 更新最优解:次数更小 或 次数相同但数值更大
            if (cost < min_cost || (cost == min_cost && p > best_prime)) {
                min_cost = cost;
                best_prime = p;
            }
        }
        
        // 输出5位素数(补前导0)
        printf("%05d&#92;n", best_prime);
        
        return 0;
    }
    
    • 1