首页 > 其他分享 >洛谷B3733 [信息与未来 2017] 基因组分析密码锁题解

洛谷B3733 [信息与未来 2017] 基因组分析密码锁题解

时间:2025-01-11 14:31:04浏览次数:3  
标签:拨盘 洛谷 target 题解 次数 拨动 下标 密码锁

[信息与未来 2017] 密码锁

题目描述

乌龟给自己的贵重物品上了密码锁。密码锁上有 5 个数字拨盘。每个数字拨盘每次向上拨使数字增加 1 (9 向上拨得到 0),向下拨使数字减少 1 (0 向下拨得到 9)。

拨盘上的数字组成一个 5 位数。只要拨盘上的数字变为素数,密码锁就会被解开。素数 (又称质数) 是只能被 1 和它自身整除的大于 1 的自然数。因为乌龟动作实在太慢,他希望你帮他计算如何开锁,使得拨动的总次数最少。

输入格式

一个5位数,表示拨盘的初始数字。

输出格式

一个5位素数,表示开启密码锁使用的素数(拨动次数最少)。如有多组解,输出满足条件的最大数。

样例 #1

样例输入 #1
01210

样例输出 #1
01319

解答思路

        首先分析题意, 我们有一个5位的密码, 想要通过拨动它来使密码为一个质数, 我们要得到的是拨动次数最小的质数, 当波动次数相同时, 我们要输出最大的那个数.

        由于密码是5位数, 我们可以枚举00000 ~ 99999, 其常数也不过十万, 再求出该范围内每个数与初始数字相差的拨动次数, 如果该数的拨动次数小于等于(为什么要等于, 因为等于的时候可以更新最大值), 就更新我们的答案, 最后将答案输出就好.

        还有一个待解决的问题是, 我们该如何求最小的拨动次数, 比如说将6拨动到0, 如果按照6 - 5 - 4 - 3 - 2 - 1 - 0 的顺序, 它的拨动次数为6次(即6 - 0); 但按照6 - 7 - 8 - 9 - 0 的顺序, 它的波动次数为4次, 这明显是更小的拨动次数, 那么我们该如何处理这种情况呢?

        可以画图来说明, 我们知道密码0 ~ 9是不断循环的, 因此我们可以将两个0 ~ 9拼接起来, 并重新定义他们的下标0 ~ 19.如图所示:

        我们再来看刚才6到0的情况, 我们发现6(下标6)可以向左到0(下标0), 同时也可以向右到0(下标10),到左边的距离为6 - 0 = 6, 到右边的距离为10 - 6 = 4; 不难发现右边的下标均对应左边的下标 + 10, 比如说左边的2的下标为2, 右边的2的下标为12.并且距离就等于下标之差, 所以, 我们可以发现, 最短的拨动次数就会出现在当前的数为start, 目标数为target, 则右边的目标数为10 + target, 最短距离只会出现在start - target 和 10 + target - start这两个数的较小值(start >= target), 如果start < target, 就反过来;

        那么, 我们就可以开始写代码了.

代码部分

#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
int p;
bool checkIsPrime(int x){
    if(x <= 1)  return false;
    for(int i = 2; i <= sqrt(x); i ++ ){
        if(!(x % i)){
            return false;
        }
    }
    return true;
}

int getCnt(int ni, int np){
    //枚举i和p的每一位
    int ans = 0;
    while(ni || np){
        int numi = ni % 10, nump = np % 10;
        if(numi < nump){
            ans += min(10 + numi - nump, nump - numi);
        }else{
            ans += min(10 + nump - numi, numi - nump);
        }
        ni /= 10, np /= 10;
    }
    return ans;
}

int main() {
    //因为密码锁只有5位, 所以可以暴力枚举1 ~ 99999, 输出拨动次数最少的最大数
    cin >> p;
    int cnt = INT_MAX;
    int ans = INT_MIN;
    for(int i = 0; i <= 99999; i ++ ){
        //记录变化的位数
        if(checkIsPrime(i)){
            //getCnt用来计算i变成p的最小拨动次数
            int cur = getCnt(i, p);
            if(cur <= cnt){
                cnt = cur;
                ans = max(ans, i);
            }
        }
    }
    //最后格式化输出含前导0的答案
    printf("%05d", ans);
    return 0;
}

标签:拨盘,洛谷,target,题解,次数,拨动,下标,密码锁
From: https://blog.csdn.net/2301_76943952/article/details/145073893

相关文章

  • 洛谷 P1102 A-B 数对(二分写法)
    题目:P1102A-B数对-洛谷|计算机科学教育新生态题目背景出题是一件痛苦的事情!相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的A+BProblem,改用A-B了哈哈!题目描述给出一串正整数数列以及一个正整数 C,要求计算出所有满足 A−B=C 的数对的个数(不同位置的数......
  • CF1759F题解
    BriefDescription给你一个\(n\)位的\(p\)进制数,第\(i\)位为\(a_i\)。请问最少要让该数加多少次\(1\),可以让数码\(0,\cdots,p−1\)都出现过(包含在中间过程出现)。Solution因为是\(p\)进制,不难发现答案一定不会超过\(p−1\),也就是说在最坏情况下就是其最后一位加至......
  • THUPC 2025 初赛 部分题题解
    持续更新中,目前只有\(\texttt{A,D,G,H,I,M}\)题题解。A.骑行计划题目描述小Rei有\(n\)天的假期,第\(i\)天她要骑行\(s_i\)分钟,每分钟骑行费用为\(c\)元。有\(m\)种骑行卡,第\(i\)种骑行卡售价\(w_i\)元,有效期\(d_i\)天,免费时间\(t_i\)分钟。小Rei可以......
  • 洛谷P2181 对角线
    对于一个 ......
  • AT_aising2020_f 题解
    AT_aising2020_fTwoSnuke题意:对于一个十元组\((a_1,a_2,b_1,b_2,c_1,c_2,d_1,d_2,e_1,e_2)\),定义它合法当且仅当满足下列条件:\(0\lea_1<a_2\)\(0\leb_1<b_2\)\(0\lec_1<c_2\)\(0\led_1<d_2\)\(0\lee_1<e_2\)\(a_1+a_2+b_1+b_2+c_1+c_......
  • AT_abc248_h [ABC248Ex] Beautiful Subsequences 题解
    题目传送门前置知识树状数组|序列分治解法考虑序列分治,设因\(\max\)和\(\min\)形成的分节点先后为\(k_{1},k_{2}\)。对于\(j\in(mid,k_{1}]\),等价于统计满足\(\max\limits_{h=i}^{mid}\{a_{h}\}-\min\limits_{h=i}^{mid}\{a_{h}\}\lej-i+k\)的\(j\)的......
  • 洛谷题单指南-线段树的进阶用法-P3157 [CQOI2011] 动态逆序对
    原题链接:https://www.luogu.com.cn/problem/P3157题意解读:长度为n的序列,序列是1~n的排列,一共m个删除操作,每一个删除之前输出逆序对。解题思路:要计算静态的逆序对,可以通过树状数组、权值线段树等方式,时间复杂度都是O(nlogn)要计算动态的逆序对,算上每一次删除,暴力做法需要O(mnlo......
  • 题解:CF1031F Familiar Operations
    传送门Solution之前有遇到类似的题,第一步先考虑转化操作和问题。对于每个数质因数分解成\(\prod{p_i^{\alpha_i}}\),我们所需要的只有\(\alpha_i\),因为只要求因子个数相同。记其为\(S_i=\{\alpha_1,\alpha_2,\dots,\alpha_k\}\),其中\(\alpha_1\geq\alpha_2\geq\dots......
  • Atcoder ABC329E Stamp 题解 [ 绿 ] [ 线性 dp ]
    Stamp:难点主要在dp转移的细节与分讨上,但通过改变状态设计可以大大简化分讨细节的题。观察首先要有一个观察:只要某一个前缀能被覆盖出来,那么无论它后面多出来多少,后面的字符串都可以帮他重新覆盖回去。这也就是dp为啥没有后效性的原因。除此之外,还要注意一个字符串不仅能在......
  • 跟我一起学 Python 数据处理(二十六):PDF 数据提取技巧与问题解决策略
    跟我一起学Python数据处理(二十六):PDF数据提取技巧与问题解决策略在Python数据处理的学习之旅中,我们已经走过了不少路程,今天继续深入探索PDF文件处理的核心技巧与方法,旨在帮助大家进一步提升数据处理能力,解决实际工作中遇到的难题。一、slate库处理PDF文件的深入......