第十一届蓝桥杯省选 7月场 题解 java实现

试题 A: 指数计算

本题总分:5 分

【问题描述】

7 月 1 日是建党日,从 1921 年到 2020 年,中国共产党已经带领中国人民

走过了 99 年。

请计算:7 ^ 2020 mod 1921,其中 A mod B 表示 A 除以 B 的余数。

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个

整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【题解】

这个题目不难,边计算边取模就行, 不用快速幂,循环2020次也能算出来。

结果:480

public static void main(String[] args) {
        System.out.println(ex(7, 2020, 1921));
    }

    public static int ex(int n, int k, int mod){
        int res = 1;
        while (k > 0) {
            if((k&1) == 1){
                res = (res * n) % mod;
            }
            n = (n * n) % mod;
            k >>= 1;
        }
        return res;
    }

试题 B: 解密

本题总分:5 分

【问题描述】

小明设计了一种文章加密的方法:对于每个字母 c,将它变成某个另外的

字符 Tc。下表给出了字符变换的规则:

字母cTc字母cTc字母cTc字母cTc
aynlAYNL
bxogBXOG
cmpoCMPO
ddquDDQU
earfEARF
fcssFCSS
gitzGITZ
hkupHKUP
invwINVW
jtwbJTWB
kjxrKJXR
lhyeLHYE
mqzvMQZV

例如,将字符串 YeRi 加密可得字符串 EaFn。

小明有一个随机的字符串,加密后为

EaFnjISplhFviDhwFbEjRjfIBBkRyY

(由 30 个大小写英文字母组成,不包含换行符),请问原字符串是多少?

(如果你把以上字符串和表格复制到文本文件中,请务必检查复制的内容

是否与文档中的一致。在试题目录下有一个文件 str.txt,第一行为上面的字符

串,后面 52 行依次为表格中的内容。)

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个

只包含 30 个大小写英文字母的字符串,在提交答案时只填写这个字符串,填写

多余的内容将无法得分。

【题解】

前面这几题都比较水。

这题可以直接对照表,找出来, 这个字符串不长。

结果:YeRikGSunlRzgDlvRwYkXkrGWWhXa

/*太水了 可以直接手算*/
        String s = "EaFnjISplhFviDhwFbEjRjfIBBkRyY";
        char[] arr = new char[s.length()];
// 为了防止出错,这里按a-z的顺序找了下来,然后做的处理
        String t1 = "yxmdacikntjhqlgoufszpwbrev";
        String t2 = "TXMDACIKNTJHQLGOUFSZPWBREV";

        char[] x = new char[26];
        char[] d = new char[26];

        for(int i = 0; i < 26; i++){
            int ix = t1.charAt(i) - 'a';
            int id = t2.charAt(i) - 'A';
            x[ix] = (char)('a' + i);
            d[id] = (char) ('A' + i);
        }

        for(int i = 0; i < s.length(); i++) {
            if(s.charAt(i) >= 'A' && s.charAt(i) <= 'Z'){
                arr[i] = d[s.charAt(i) - 'A'];
            }else{
                arr[i] = x[s.charAt(i) - 'a'];
            }
        }

        System.out.println(String.valueOf(arr));

试题 C: 跑步训练

本题总分:10 分

【问题描述】

小明要做一个跑步训练。

初始时,小明充满体力,体力值计为 10000。如果小明跑步,每分钟损耗

600 的体力。如果小明休息,每分钟增加 300 的体力。体力的损耗和增加都是

均匀变化的。

小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循

环。如果某个时刻小明的体力到达 0,他就停止锻炼。

请问小明在多久后停止锻炼。为了使答案为整数,请以秒为单位输出答案。

答案中只填写数,不填写单位。

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个

整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【题解】

模拟题是最好做的,这题按题目给的意思模拟就行。

要注意,一次训练一分钟,某个时刻小明的体力到达 0,他就停止锻炼。

结果:3880

public static int f(int n){// n : 初始时的体力
        int res = 0;
        boolean t = true;
        while(n > 0){
            if(t) {
                n -= 600;
                if(n < 0){
                    n += 600;
                    break;
                }
            }
            else n += 300;
            t = !t;
            res ++;
        }
        return res * 60 + n / 10;
    }

试题 D: 合并检测

本题总分:10 分

【问题描述】

新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情,A 国准

备给大量民众进病毒核酸检测。

然而,用于检测的试剂盒紧缺。

为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人(k

个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k

个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明

至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,

如果检测前 k 1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中

不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用

了 k + 1 个试剂盒完成了 k 个人的检测。

A 国估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能

最节省试剂盒?

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个

整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【题解】

这题我没有想出怎么做。

我是直接猜到的。后来我也看了写题解答案时10.

猜:题目告诉我们感染率是1%,呈均匀分布。

我们就假设100个人中一定有1个人感染

将100分成n组每组k个人

尝试一下那种分最少就好

结果:10

试题 E: REPEAT 程序

本题总分:15 分

【问题描述】

附件 prog.txt 中是一个用某种语言写的程序。

其中 REPEAT k 表示一个次数为 k 的循环。循环控制的范围由缩进表达,

从次行开始连续的缩进比该行多的(前面的空白更长的)为循环包含的内容。

例如如下片段:

REPEAT 2:

​ A = A + 4

​ REPEAT 5:

​ REPEAT 6:

​ A = A + 5

​ A = A + 7

​ A = A + 8

A = A + 9

A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的

循环两次中。

REPEAT 6: 所在的行到 A = A + 7 所在的行都在 REPEAT 5: 循环中。

A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。

请问该程序执行完毕之后,A 的值是多少?

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个

整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

试题 F: 分类计数

时间限制: 1.0s 内存限制: 512.0MB 本题总分:15 分

【问题描述】

输入一个字符串,请输出这个字符串包含多少个大写字母,多少个小写字

母,多少个数字。

【输入格式】

输入一行包含一个字符串。

【输出格式】

输出三行,每行一个整数,分别表示大写字母、小写字母和数字的个数。

【样例输入】

1+a=Aab

【样例输出】

131

【评测用例规模与约定】

对于所有评测用例,字符串由可见字符组成,长度不超过 100。

【题解】

用3个变量分别储存大写字母、小写字母、数字,扫描一遍数组,就行。

测试用例 n<=1018, 所以不会超时

Scanner sc = new Scanner(System.in);
        String s = sc.next();
        int shu = 0;
        int xiao = 0;
        int da = 0;
        for(int i = 0; i < s.length(); i++) {
            if(s.charAt(i) >= 'A' && s.charAt(i) <= 'Z'){
                da ++;
            }else if(s.charAt(i) >= 'a' && s.charAt(i) <= 'z'){
                xiao ++;
            }else if(s.charAt(i) >= '0' && s.charAt(i) <= '9'){
                shu ++;
            }
        }
        System.out.println(da + "\n" + xiao + "\n" + shu);

试题 G: 整除序列

时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分

【问题描述】

有一个序列,序列的第一个数是 n,后面的每个数是前一个数整除 2,请输

出这个序列中值为正数的项。

【输入格式】

输入一行包含一个整数 n。

【输出格式】

输出一行,包含多个整数,相邻的整数之间用一个空格分隔,表示答案。

【样例输入】

20

【样例输出】

20 10 5 2 1

【评测用例规模与约定】

对于 80% 的评测用例,1 ≤ n ≤ 109。

对于所有评测用例,1 ≤ n ≤ 1018。

【题解】

这题也直接按照题目意思写程序就行。

因为每次是除2,所以时间复杂度是lgn的不会超超时。

Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        StringBuilder s = new StringBuilder();
        while(n > 0){
            s.append(n);
            s.append(" ");
            n >>= 1;
        }
        System.out.println(s.toString());

试题 H: 走方格

时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分

【问题描述】

在平面上有一些二维的点阵。

这些点的编号就像二维数组的编号一样,从上到下依次为第 1 至第 n 行,

从左到右依次为第 1 至第 m 列,每一个点可以用行号和列号来表示。

现在有个人站在第 1 行第 1 列,要走到第 n 行第 m 列。只能向右或者向下

走。

注意,如果行号和列数都是偶数,不能走入这一格中。

问有多少种方案。

【输入格式】

输入一行包含两个整数 n, m。

【输出格式】

输出一个整数,表示答案。

【样例输入】

3 4

【样例输出】

2

【样例输入】

6 6

【样例输出】

0

【评测用例规模与约定】

对于所有评测用例,1 ≤ n ≤ 30, 1 ≤ m ≤ 30。

【题解】

测试用例 1 ≤ n ≤ 30, 1 ≤ m ≤ 30 如果用递归来模拟,时间复杂度是2^n肯定会超时(忽略不走的路径)。 所以这题用dp做30*30不会超时。

public static int dfs(int n, int m) {
// n m 皆为题目中的n m
        int[][] dp = new int[n + 1][m + 1];
        dp[n][m] = 1;
        for (int i = n; i > 0; i--) {
            for (int j = m; j > 0; j--) {
                if(i < n && ((i + 1) % 2 != 0 || j % 2 != 0)){
                    dp[i][j] += dp[i + 1][j];
                }
                if(j < m && ((j + 1) % 2 != 0 || i % 2 != 0)){
                    dp[i][j] += dp[i][j + 1];
                }
            }
        }
        return dp[1][1];
    }

试题 I: 字符串编码

时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分

【问题描述】

小明发明了一种给由全大写字母组成的字符串编码的方法。对于每一个大

写字母,小明将它转换成它在 26 个英文字母中序号,即 A → 1, B → 2, … Z →

26。

这样一个字符串就能被转化成一个数字序列:

比如 ABCXYZ → 123242526。

现在给定一个转换后的数字序列,小明想还原出原本的字符串。当然这样

的还原有可能存在多个符合条件的字符串。小明希望找出其中字典序最大的字

符串。

【输入格式】

一个数字序列。

【输出格式】

一个只包含大写字母的字符串,代表答案

【样例输入】

123242526

【样例输出】

LCXYZ

【评测用例规模与约定】

对于 20% 的评测用例,输入的长度不超过 20。

对于所有评测用例,输入的长度不超过 200000。

【题解】

这题的思路就是贪心。

注意字典序与我们平常所看到的数字比大小不一样。如果两个字符串的第一个字符是 a 和 z 那么无论 首字符是a的字符串多长它一定会在首字符是z的字符串前面(a字符串 < z字符串)。贪心的话我们只要保证前面的字符足够大就行。

扫描一遍字符串 n 的时间不会超时。

Scanner sc = new Scanner(System.in);
        String s = sc.next();
        StringBuilder res = new StringBuilder();

        for(int i = 0; i < s.length(); i++) {
            int k = s.charAt(i) - '0';
            if(k <= 2){
                int t = k * 10 + s.charAt(i + 1) - '0';
                // 因为’A‘是1 所以要减一
                if(t <= 26){
                    res.append((char) ('A' + t - 1));
                    i ++;
                    continue;
                }
            }
            res.append((char)('A' + k - 1));
        }
        System.out.println(res.toString());

试题 J: 整数小拼接

时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分

【问题描述】

给定义个长度为 n 的数组 A1, A2, · · · , An。你可以从中选出两个数 Ai 和 Aj (i 不等于 j),然后将 Ai 和 Aj 一前一后拼成一个新的整数。例如 12 和 345 可

以拼成 12345 或 34512 。注意交换 Ai 和 Aj 的顺序总是被视为 2 种拼法,即便

是 Ai = Aj 时。

请你计算有多少种拼法满足拼出的整数小于等于 K。

【输入格式】

第一行包含 2 个整数 n 和 K。

第二行包含 n 个整数 A1, A2, · · · , An。

【输出格式】

一个整数代表答案。

【样例输入】

4 33

1 2 3 4

【样例输出】

8

【评测用例规模与约定】

对于 30% 的评测用例,1 ≤ N ≤ 1000, 1 ≤ K ≤ 108, 1 ≤ Ai ≤ 104。

对于所有评测用例,1 ≤ N ≤ 100000,1 ≤ K ≤ 1010,1 ≤ Ai ≤ 109。

【题解】

这题是整套题目里最难的一个题目。

整体思路是 贪心+二分查找

先排序然后找出最后一个满足条件的数。

时间复杂度 排序 nlgn + nlgn(n次二分 就是 nlgn)

我们不知道对不对。我用暴力的解和这个对照过,么出现错。

public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
        System.out.println(f(arr, n, k));
    }
public static int f(int[] arr, int n, int k) {
        Arrays.sort(arr);
        int res = 0;
        for (int i = 0; i < n; i++) {
            int left = 0;
            int right = n - 1;
            while(left < right){
                int mid = left + right + 1 >> 1;
                if(Integer.parseInt(arr[i] + "" + arr[mid]) > k){
                    right = mid - 1;
                }else left = mid;
            }
            if(Integer.parseInt(arr[i] + "" + arr[left]) <= k){
                res += left >= i ? left : left + 1;
            }
        }
        return res;
    }

这题并没有说明,如果 Ai 一样算不算。

比如 1 1 1 1 k = 100

算 1(处理重复) 种拼法还是 12 种(不处理重复元素)

上面这个解法把相同的元素,算了重复的。

如果要处理重复元素的话,扫描一遍数组把相同的元素压在一起,用一个map记录 某个数出现了几次。

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值