第十四届蓝桥杯三月真题刷题训练——第 21 天

Posted 小羊不会飞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十四届蓝桥杯三月真题刷题训练——第 21 天相关的知识,希望对你有一定的参考价值。

目录

第 1 题:灭鼠先锋

问题描述

运行限制

代码:

思路:

第 2 题:小蓝与钥匙

问题描述

答案提交

运行限制

代码:

思路 :

第 3 题:李白打酒加强版 

第 4 题:机房 


第 1 题:灭鼠先锋

问题描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

灭鼠先锋是一个老少咸宜的棋盘小游戏,由两人参与,轮流操作。

灭鼠先锋的棋盘有各种规格,本题中游戏在两行四列的棋盘上进行。游戏的规则为:两人轮流操作,每次可选择在棋盘的一个空位上放置一个棋子,或在同一行的连续两个空位上各放置一个棋子,放下棋子后使棋盘放满的一方输掉游戏。

小蓝和小乔一起玩游戏,小蓝先手,小乔后手。小蓝可以放置棋子的方法很多,通过旋转和翻转可以对应如下四种情况:

XOOO XXOO OXOO OXXO
OOOO OOOO OOOO OOOO

其中 O 表示棋盘上的一个方格为空,X 表示该方格已经放置了棋子。

请问,对于以上四种情况,如果小蓝和小乔都是按照对自己最优的策略来玩游戏,小蓝是否能获胜。如果获胜,请用 V 表示,否则用 L 表示。请将四种情况的胜负结果按顺序连接在一起提交。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码:

package 第十四届蓝桥杯三月真题刷题训练.day21;

/**
 * @author yx
 * @date 2023-03-24 8:27
 */
public class 灭鼠先锋 
    public static void main(String[] args) 
        System.out.println("LLLV");
    

思路:

(1)因为这个题目已经把先手的四种情况进行了说明,所以就非常好想

(2)我们只需要找到一种后手下棋思路让先手必输的情况,那对于后手来说就是最优方法

(3)分别在纸上画一下下棋思路即可

第 2 题:小蓝与钥匙

问题描述

小蓝是幼儿园的老师, 他的班上有 28 个孩子, 今天他和孩子们一起进行了 一个游戏。

小蓝所在的学校是寄宿制学校, 28 个孩子分别有一个自己的房间, 每个房 间对应一把钥匙, 每把钥匙只能打开自己的门。现在小蓝让这 28 个孩子分别将 自己宿舍的钥匙上交, 再把这 28 把钥匙随机打乱分给每个孩子一把钥匙, 有 28!=28×27×⋯×1 种分配方案。小蓝想知道这些方案中, 有多少种方案恰有 一半的孩子被分到自己房间的钥匙 (即有 14 个孩子分到的是自己房间的钥匙, 有 14 个孩子分到的不是自己房间的钥匙)。

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M

代码:

package 第十四届蓝桥杯三月真题刷题训练.day21;

/**
 * @author yx
 * @date 2023-03-24 8:51
 */
public class 小蓝与钥匙 
    static int N=14;
    public static void main(String[] args) 
        /**
         * 1、先从28个人里面选14个人给定它们的钥匙,一共有C14 28 种选法
         * 2、剩下的14个钥匙分别发给不同的人,使他们拿到的都不是自己的钥匙
         * 3、后半部分属于全错排列问题,用递推来做
         */
        /*
        全错排列问题:f(x)=f(x-1)+f(x-2)
        f(0)=0;
        f(1)=0;
        f(2)=1;
         */
        //排列组合:2006329977
        long C_14_28=paiLie();
        long f1=0;
        long f2=1;
        long temp=0;
        for (int i = 3; i <= 14; i++) 
            temp=f2;
            f2=(i-1)*(f1+f2);
            f1=temp;
        
        System.out.println(f2*C_14_28);
    

    //
    static long paiLie()
        long ans=1;
        for (long i = 0; i < 14; i++) 
            ans=ans*(28-i)/(i+1);
        
        return ans;
    

思路 :

(1)先从28个人里面选14个人给定它们的钥匙,一共有C14 28 种选法

    static long paiLie()
        long ans=1;
        for (long i = 0; i < 14; i++) 
            ans=ans*(28-i)/(i+1);
        
        return ans;
    

(2)剩下的14个钥匙分别发给不同的人,使他们拿到的都不是自己的钥匙,即全错排问题

(3)全错排公式:f(x)=(N-1) * [f(x-1)+f(x-2)]

(4)推导过程:

  • 首先是初始值:f1=0; f2=1; f3=9这几项是可以自己手撸的
  • 当i>3,很明显手撸不太行,我们静下心来分析,要找其内在的规律
  • 设N个人为a,b,c,d...,N张卡为A,B,C,D...
  • 若a拿b的卡B,b也拿a的卡A,则显然只剩下N-2个人拿卡,自然是f(N-2)种了(好理解)
  • 若a拿b的卡B,b没拿a的卡A,则显然与N-1个人拿卡问题一样,自然是f(N-1)种了(不好理解)
  • 为啥是f(N-1)种呢?注意:这里的b没拿卡A,就相当于在N个数中a没拿卡A一样的道理,在N-1个数字中,b的卡片B被a拿走了,而B又不能拿A,其实就是把卡A变相看作是卡B的平替那是不是就相当于看作了N-1个数字进行错排
  • a不一定拿B,只要是B,C,D...(N-1个)中的一个就可以了,所以在f(N-1)+f(N-2)再乘上N-1就行了.
  • 得出递推公式:f(N)=(N-1)*[f(N-1)+f(N-2)]

第 3 题:李白打酒加强版 

第 4 题:机房 

第十四届蓝桥杯三月真题刷题训练——第 12 天

目录

第 1 题:0的个数

问题描述

输入格式

输出格式

评测用例规模与约定

运行限制

代码:

第 2 题:超级质数

问题描述

答案提交

运行限制

代码:

分析:

第 3 题:卡牌_二分_快读

问题描述

输入格式

输出格式

样例输入

样例输出

样例说明

评测用例规模与约定

运行限制

代码:

​分析:

第 4 题:染色时间


第 1 题:0的个数

问题描述

给定一个正整数 n ,请问 n 的十进制表示中末尾总共有几个 0 ?

输入格式

输入一行包含一个正整数 nn。

输出格式

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

样例输入

20220000

样例输出

4

评测用例规模与约定

对于所有评测用例,1 <= n <= 1000000000。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码:

package 第十四届蓝桥杯三月真题刷题训练.day12;

import java.io.*;

/**
 * @author yx
 * @date 2023-03-15 8:19
 */
public class 零的个数 
    static PrintWriter out =new PrintWriter(System.out);
    static BufferedReader ins=new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer in=new StreamTokenizer(ins);
    /**
     * 输入
     * in.nextToken()
     * int a= (int)in.nval;
     *
     * 输出
     * out.print();
     * out.flush();
     */
    public static void main(String[] args) throws IOException 
        in.nextToken();
        int n=(int) in.nval;
        int temp=0;
        int ans=0;
        while (true)
            temp=n%10;
            if(temp!=0)
                break;
            else 
                ans++;
            
            n/=10;
        
        out.println(ans);
        out.flush();
    

第 2 题:超级质数

问题描述

如果一个质数 P 的每位数字都是质数, 而且每两个相邻的数字组成的两位 数是质数, 而且每三位相邻的数字组成的三位数是质数, 依次类推, 如果每相 邻的 k 位数字组成的 k 位数都是质数, 则 P 称为超级质数。

如果把超级质数 P 看成一个字符串, 则这个超级质数的每个子串都是质 数。

例如, 53 是一个超级质数。

请问, 最大的超级质数是多少?

答案提交

这是一道结果填空的题, 你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码:

package 第十四届蓝桥杯三月真题刷题训练.day12;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

/**
 * @author yx
 * @date 2023-03-15 15:10
 */
public class 超级质数 
    static PrintWriter out =new PrintWriter(System.out);
    static BufferedReader ins=new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer in=new StreamTokenizer(ins);
    /**
     * 输入
     * in.nextToken()
     * int a= (int)in.nval;
     *
     * 输出
     * out.print();
     * out.flush();
     */
    public static void main(String[] args) 
        for (int i = 1000000; i>=2 ; i--) 
            if(isCheck(i))
                System.out.println(i);
                return;
            
        
    

    static boolean isCheck(int n)
        String s=n+"";
        int length=s.length();
        for (int i = 0; i < length ; i++) 
            for (int j = i+1; j <= length ; j++) 
                int temp=Integer.parseInt(s.substring(i,j));
                if(!isPrime(temp))//如果不是质数就返回false
                    return false;
                
            
        
        return true;
    
    static boolean isPrime(int n)
        if(n==1)return false;
        for (int i = 2; i <= Math.sqrt(n) ; i++) 
            if(n%i==0)
                return false;
            
        
        return true;
    



分析:

思路:

1、质数判断

2、数值切割

第 3 题:卡牌_二分_快读

问题描述

这天, 小明在整理他的卡牌。

他一共有 n 种卡牌, 第 i 种卡牌上印有正整数数 i(i∈[1,n]), 且第 i 种卡牌 现有 ai​ 张。

而如果有 n 张卡牌, 其中每种卡牌各一张, 那么这 nn 张卡牌可以被称为一 套牌。小明为了凑出尽可能多套牌, 拿出了 m 张空白牌, 他可以在上面写上数 i, 将其当做第 i 种牌来凑出套牌。然而小明觉得手写的牌不太美观, 决定第 ii 种牌最多手写 bi​ 张。

请问小明最多能凑出多少套牌?

输入格式

输入共 3 行, 第一行为两个正整数 n,m。

第二行为 n 个正整数 a1,a2,…,an。

第三行为 n 个正整数 b1,b2,…,bn​ 。

输出格式

一行, 一个整数表示答案。

样例输入

4 5
1 2 3 4
5 5 5 5

样例输出

3

样例说明

这 5 张空白牌中, 拿 2 张写 1 , 拿 1 张写 2 , 这样每种牌的牌数就变为了 3,3,3,4, 可以凑出 3 套牌, 剩下 2 张空白牌不能再帮助小明凑出一套。

评测用例规模与约定

对于 30%的数据, 保证 n≤2000;

对于 100% 的数据, 保证 n≤2×10^5;ai,bi≤2*n;m≤n^2 。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M

代码:

package 第十四届蓝桥杯三月真题刷题训练.day12;

import java.io.*;
import java.util.Scanner;

/**
 * @author yx
 * @date 2023-03-15 16:45
 */
public class 卡牌_二分_非快读必超时 
    static PrintWriter out =new PrintWriter(System.out);
    static BufferedReader ins=new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer in=new StreamTokenizer(ins);
    /**
     * 输入
     * in.nextToken()
     * int a= (int)in.nval;
     *
     * 输出
     * out.print();
     * out.flush();
     */
    static int[]a;
    static int[]b;
    static int n;
    static long m;
    public static void main(String[] args) throws IOException 
        String[] s=ins.readLine().split(" ");
        n=Integer.parseInt(s[0]);
        m=Long.parseLong(s[1]);
        a=new int[n];
        b=new int[n];
        String[] s2=ins.readLine().split(" ");
        for (int i = 0; i < n; i++) 
            a[i]=Integer.parseInt(s2[i]);
        
        String[] s3=ins.readLine().split(" ");
        for (int i = 0; i < n; i++) 
            b[i]=Integer.parseInt(s3[i]);
        
        int l=0;
        int r=2*n;
        int ans=0;
        while (l<=r)
            int mid=(l+r)/2;
            if(check(mid))
                ans=mid;
                l=mid+1;
            else 
                r=mid-1;
            
        
        out.println(ans);
        out.flush();
    
    static boolean check(int t)
        long temp=m;//记录空白卡牌
        for (int i = 0; i < n; i++) 
            if(a[i]>=t)continue;
            if(b[i]+a[i]<t)return false;
            if(temp+a[i]<t)return false;
            if(t-a[i]<=temp)
                temp-=(t-a[i]);
            else
                return false;
            
        
        return true;
    

分析:

这道题目非常综合,考察了二分以及Java的IO流输入输出,下面是我总结的一些要点!

(1)这道题目是通过二分的手段来找到最多的能凑到的牌的套数

我自己的一套二分模板(经供参考):

while (l<=r)
            int mid=(l+r)/2;
            if(check(mid))
                ans=mid;
                l=mid+1;
            else 
                r=mid-1;
            
        

二分的难点有两个:

  1. 二分边界,即L和R的退出条件
  2. check函数的函数体实现

(2)这道题目充分的体现了Java的不足,普通的Scanner输入只能拿到30%的分数,这道题目要想拿满分必须要使用Java的I/O流输入

下面是我的题解代码中每次都会出现的IO流模板:

    static PrintWriter out =new PrintWriter(System.out);
    static BufferedReader ins=new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer in=new StreamTokenizer(ins);
    /**
     * 输入
     * in.nextToken()
     * int a= (int)in.nval;
     *
     * 输出
     * out.print();
     * out.flush();
     */

(3)在做这道题目的时候,我发现Scanner和BufferReader不能同时使用,会出现输入异常,这个点希望大家在做题的时候注意一下!!

第 4 题:染色时间

拍了一天戏,脑袋晕晕的,下次补!

以上是关于第十四届蓝桥杯三月真题刷题训练——第 21 天的主要内容,如果未能解决你的问题,请参考以下文章

第十四届蓝桥杯三月真题刷题训练——第 22 天

第十四届蓝桥杯三月真题刷题训练——第 12 天

第十四届蓝桥杯三月真题刷题训练——第 23 天

第十四届蓝桥杯大赛——真题训练第11天

2022 第十四届蓝桥杯模拟赛第三期(题解与标程)

第十四届蓝桥杯C/C++_大学B组省赛真题