• 【蓝桥杯软件赛 零基础备赛20周】第3周——填空题


    报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集
    20周的完整安排请点击:20周计划

    00. 2023年第14届参赛数据

    看到一张图,2023年第14届的参赛数据:
    在这里插入图片描述
    各语言组参赛情况:
      C/C++组参赛81625人,占比63.9%;
      Java组参赛24652人,占比19.3%;
      Python组参赛21509人,占比16.8%。

    2021-2022-2023,过去3年各语言占比变化:
      C/C++组:67%–68%–64%
      java组:24%–19%–19%
      python组:9%–13%–17%

    0. 上一周答疑

    问题1:在比赛时可以自行携带计算器吗?

    答:能使用赛场电脑自带的计算器和电脑里的任何软件。不能带资料和电子设备。蓝桥杯相当于闭卷考试。这是考场纪律:《蓝桥杯大赛个人赛(软件类/电子类)比赛管理办法》

    问题2:到什么平台做入门题?

    答:基础题很多平台都有,例如蓝桥杯题库,你们学校的OJ,洛谷,newOJ等等。我在第2周的刷题建议里,给的简单题是蓝桥杯题库的。好处一是熟悉蓝桥杯比赛环境,二是它的题目有很多人写题解,方便看看别人的答案对照学习。

    问题3:什么书更适合初学者?

    答:《深入浅出程序设计竞赛(基础篇)》最“入门”,它前一半讲c语言,后一半讲了一些基本算法。《程序设计竞赛专题挑战教程》是算法入门,它没有讲c语言,而是讲了50多个基础的算法知识点。

    问题4:《程序设计竞赛专题挑战教程》里面有讲数据结构吗?

    答:有,《程序设计竞赛专题挑战教程》的目录, “第3章 基础数据结构,C/C++和python的数据结构实现”。

    问题5:有python的算法竞赛书吗?

    答:目前算法竞赛书,只有《程序设计竞赛专题挑战教程》是C/C++、Python的合体书。似乎没有其他的python语言的算法竞赛书。java的算法竞赛书好像一本也没有。如果大家发现有,推荐一下。

    问题6:那Java和Python赛道是不是也可以跟着您的20周计划进行呢?

    答:可以。如果没有java或python代码,你可以用chatgpt之类的工具,把C++代码转成java或python代码,转换的质量很高。

    问题7:几种语言哪个难一些?

    答:难的是算法和思维,语言本身不算难。如果你是问得奖难度,以前是python容易一点。不过如果大家都觉得python容易,都来python组,那就不好说了。

    问题8:如果我只学了c语言的语法,接下来看这本书《算法竞赛》可以吗?

    答:《算法竞赛》是算法大全,包括了初级、中级、高级知识点,可以陪伴整个算法竞赛的学习过程。
    《算法竞赛》的初级内容是基本数据结构。从知识点学习的进展来看,学完c语言之后就可以开始学基本数据结构了。

    但是如果学c语言时编程太少,编程能力不够,计算思维也没有建立,这个时候就立刻开始学数据结构和算法,会很吃力的。就像一个瘦弱的人学武功,先需要强身健体,然后再去学武术套路。还很瘦的时候就急着搞武术套路,效果很差;很多动作即使勉强去做,也做不到位。

    所以先需要做一些模拟题提高编码能力、建立计算思维。模拟题就是不要什么数据结构和算法的题目。就是这几周我建议的题目。

    学编程最重要的是多做编程题目,多编码。如果看书、看视频是5%,那么做题是95%

    问题9:ACM/ICPC的难度和蓝桥杯的难度相比?

    答:“零基础备赛20周–第2周”中提到:“算法竞赛除了蓝桥杯,还有ICPC、CCPC。蓝桥杯省赛是普及赛,参加人多得奖人多。蓝桥杯国赛、ICPC、CCPC都是精英赛,参加人少得奖人少。蓝桥杯国赛和ICPC差不多。”

    问题10:打算考研的话,对于自己来说竞赛经历和工程经历哪个更重要?找工作面试,是算法重要还是工程经验重要?

    答:考研首先是成绩,成绩过关后,面试一般能过,但是研究生毕业还是要找工作。如果是找工作,面试有好几轮,有一轮是算法,有一轮是工程经验。所以,只要你毕业以后从事计算机相关工作,都逃不了算法题。有的公司,工作十年的资深工程师去社招,还需要做算法题。

    问题11:ACM/ICPC一队3人,3个人一般都怎么分工的?

    答:等你蓝桥杯省赛二等以上,开始找人组队参加ACM/ICPC了,就知道怎么分工了。总体来说,三人需要水平差不多,不要指望牛人能带动弱鸡。每人到中等水平之上后,就是中级知识点都学好之后,再做个分工,有人深入图论,有人深入数论,有人深入DP,等等。

    问题12:有很多人在说打ACM/ICPC的性价比在降低,学习一年算法打蓝桥杯之后转战学项目的技术栈会不会更好 ?

    答:是的,ACM/ICPC是精英赛,得奖的人不多。蓝桥杯省赛一等奖的去参加ACM才有可能得奖。对于想在算法上获得更深的造诣的同学,ACM/ICPC是证明你实力的最佳比赛!

    1. 填空题介绍

    蓝桥杯省赛10题中有2题填空,每题只有5分。

    填空题只需要填写答案,不需要解题过程,可以用编码、纸上演算、软件工具等各种方法求解,我统一归纳为“手算题”。

    近年来,填空题发生了比较大的变化:
    (1)填空题分值大大降低。从第1届到2021年第12届蓝桥杯,填空题有5题,分值占总分的45/150;从2022年第13届蓝桥杯开始,填空题减少到2题,只占总分的10/150
    (2)填空题少了,难度也上升了,有些技巧用不上。四个技巧:“巧用编辑器、眼看手数、巧用Excel、巧用Python”,前三个“巧用编辑器、眼看手数、巧用Excel”现在不太有用了,但是Python仍然非常有用。很多填空题用到了复杂的推理、算法。
    (3)2023年的所有填空题都必须要编程才能得到结果。

    2. Python在填空题中的应用

    填空题遇到字符、大数字、日期问题,Python是首选,可以直接模拟,不用什么编码技巧。即使是参加C/C++、Java组比赛,也要学一些Python,以方便手算,或用来做对比测试。写Python代码既简单又快,代码长度一般比C/C++、Java短很多,例如30行的C++代码,用Python写只需要20行。

    有同学担心:“我参加的是C/C++组,比赛的时候机器上有Python编译器吗?”
    根据往年经验,不用担心。比赛机器上同时装有C/C++、Java、Python编译器,都能用。

    3. 本周刷题

    本周刷填空题,蓝桥杯2015-2023合集,到蓝桥题库,标签选2023,题目名字可以参考文章目录标题,也可以在第4节中直接点击链接。

    2015-2021年,每组前5题是填空题。
    2022-2023年,每组前2题是填空题。

    注意,有很多填空题可能需要算法。初学者不会算法,可以先试试用暴力做。如果暴力做不了就算了。

    4. 2023年第14届省赛填空题解析

    本节解析2023年4月第14届省赛所有的填空题,共24题。

    先概述一下这一年的填空题。
    (1)题目的重复。一共24题,其中有5题重复使用了3、4次:求和、工作时长、与或异或、特殊日期、 分糖果。去掉重复,24题实际仅有13题。
    (2)知识点考核。有些题有多种解法,没有学过任何算法的同学也能做。13道不重复的题中:
      10题:不需要算法。在这些题目中,日期、排序比较常见,我们要多练习。
      3题:必须用DFS。DFS是蓝桥杯省赛最常出现的考点,没有之一。
    (3)难度。13道不重复的题中:
      极简2题,学过语言就能做。
      简单5题,需要经过一定的训练。
      中等4题,需要更多训练。
      难题2题,训练多了也不一定会。

    3.1 C/C++语言组

    A组-试题A-幸运数

    蓝桥题库-幸运数
    说明:模拟题,可以暴力做。
    解析1: 直接暴力检查1~100000000的所有数,运行时间大约1分钟,能接受。
      没有学过任何算法的初学者也能做。参考代码:

    #include
    using namespace std;
    inline bool check(int x){
        string s;
        while(x)  s += (char)(x % 10 + '0'), x /= 10;
        int n = s.size();
        if(n % 2 == 1)  return false;     //约束1:偶数个数位
        int sum1 = 0, sum2 = 0;
        for(int i = 0; i < n / 2; i++){
            sum1 += s[i] - '0';
            sum2 += s[i + n / 2] - '0';
        }
        return sum1 == sum2;            //约束2:前半部分和等于后半部分
    }
    int main(){
         int ans = 0;
         for(int i = 1; i <= 100000000; i++)
             if(check(i))  ans++;
         cout<<ans<<endl;
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    解析2:本题的正解是思维题:凑出幸运数。
      因为幸运数是一个偶数,左边一半的和等于右边一半的和,那么可以这样做:先给出左边一半的数字,然后凑出右边一半的数字,让步两者的和相等。
      定义 A [ i ] [ j ] A [ i ] [ j ] A[i][j] 表示 i i i位数且和为 j j j的数字个数。例如A[1][5]=1表示一位数,且和为5,那么只有一个数字5;再例如A[2][4]=4,有13、22、31、40四个数字。
       i i i位的数,有多少种和?例如3位数,最小是100,最大是999,所以和的范围是 1 ∽ 3 × 9 1\backsim3\times9 13×9
      一个 2 i 2 i 2i位的数字,左一半和为 j j j A [ i ] [ j ] A [ i ] [ j ] A[i][j]种可能,每一种都可以对应右一半和为 j j j A [ 1 ] [ j ] 、 A [ 2 ] [ j ] 、 . . . 、 A [ i ] [ j ] A [ 1 ] [ j ] 、 A [ 2 ] [ j ] 、 . . . 、 A [ i ] [ j ] A[1][j]A[2][j]...A[i][j],例如左一半是数字23,右一半可以是05、14、23、32、41、50。
      下面用python写代码:

    A = [[0] * 50 for i in range(5)]
    idx = 0
    for x in range(1, 10000):     # 1~9999的所有数字
        x = [int(i) for i in list(str(x))]
        A[len(x)][sum(x)] += 1
    ans = 0
    for i in range(1, 5):              #左一半:1位~4位
        for j in range(1, i * 9 + 1):  #和的范围是1~i*9
            for k in range(1, i + 1):  #右一半:只要比i位少就行,前面可以补0
                ans += A[i][j] * A[k][j]
    print(ans)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这个代码的计算次数很少,计算效率很高。

    A组-试题B-有奖问答

    蓝桥题库-有奖问答

    说明: DFS,或者DP。

    解析1:

    暴力的方法是用DFS搜索所有情况。下面的代码计算量很大,因为14、15行继续做2次dfs,计算复杂度是 O ( 2 n ) O(2^n) O(2n)。当n=30时,约十亿次,运行时间1分钟。出题人考核的就是DFS。故意让n=30,用DFS刚好能1分钟运行结束得到答案;如果让n更大一些,运行时间就太长了,DFS就不合适了。这里不要用python写代码,运行慢,而且容易栈溢出。

    #include
    using namespace std;
    int ans=0;
    void dfs(int x,int score,int k){ //x:第x题; score:得分; k:对错
        if(k==0) score=0;  //答错了归零
        else{
            score+=10;     //答对了
            if(score==100) return;
        }
        if(x==30){         //共30题
            if(score==70) ans++;  //答案加1
            return;
        }
        dfs(x+1,score,0);  //0: 答错了
        dfs(x+1,score,1);  //1:答对了
    }
    int main(){
        dfs(0,0,0);
        cout<<ans;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    解析2:

    这题的正解是DP。下面代码的计算量是7、8行的两重for循环,仅循环30*9次。

    #include
    using namespace std;
    int ans;
    int dp[31][10];//dp[i][j]代表回答了i道题目时得到了j*10的分数的 总方案数
    int main(){
        dp[0][0]=1;
        for(int i=1;i<=30;i++)
            for(int j=0;j<=9;j++){
            //j==10 得到100分 游戏直接结束,不合题意中得到70分,因而不必枚举
                //分为答对和没有答对两种情况
                if(j!=0)
                    dp[i][j]=dp[i-1][j-1];
                else {
                    for(int p=0;p<=9;p++)
                        dp[i][0]+=dp[i-1][p];
                }
            }
        for(int i=0;i<=30;i++)
          ans+=dp[i][7]; //得70分的总方案数
        cout<<ans;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    B组-试题A-日期统计

    蓝桥题库-日期统计

    说明: 模拟题,暴力法。解法很多。

    解析1:

    暴力搜所有数字,看能不能组合成合法日期。代码的运行时间也不长,只有几秒。

    #include 
    using namespace std;
    int num[110];
    int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    
    int main() {
        for (int i=0;i<100;i++)  cin >>num[i];  //输入100个数
        set<int> ans;
        for (int i = 0; i < 100; i++)
            for (int j = i + 1; j < 100; j++)
                for (int k = j + 1; k < 100; k++)
                    for (int v = k + 1; v < 100; v++) //前4个数字构成年
                    {
                        int y = num[i] * 1000 + num[j] * 100 + num[k] * 10 + num[v];   //年
    
                        if (y == 2023) {                       //找到了年,再找月、日
                            for (int m = v + 1; m < 100; m++)
                                for (int n = m + 1; n < 100; n++)
                                    for (int o = n + 1; o < 100; o++)
                                        for (int p = o + 1; p < 100; p++)
                                        {
                                            int mon = num[m] * 10 + num[n];   //月
                                            int d = num[o] * 10 + num[p];     //日
    
                                            if ((mon >= 1 && mon <= 12) && (d >= 1 && d <= days[mon]))
                                            {
                                                int temp = mon * 100 + d;
                                                ans.insert(temp);      //用set去重
                                            }
                                        }
                            break;
                        }
                    }
        cout << ans.size();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    解析2:

    更好的暴力法,是反过来操作。不是在100个数字中找出8个来构成合法日期,而是生成2023年的365个日期,看有多少能在100个数字中找到。

    #include 
    using namespace std;
    int num[110];
    int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    
    int main() {
        for (int i=0;i<100;i++)   cin >>num[i];  //输入100个数
        int ans = 0;
        for (int i = 1; i <= 12; i++) {
            for (int j = 1; j <= days[i]; j++) {
                string str = "2023";    //年
                if (i < 10)  str += "0";
                str += to_string(i);     //+月
                if (j < 10)str += "0";
                str += to_string(j);     //+日
                int k = 0;
                for (int v = 0; v < 100 && k < 8; v++)  //在100个数中找这个日期
                    if (num[v] == str[k] - '0')
                        k++;
                if (k >= 8) ans++;
            }
        }
        cout << ans << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    日期问题用Python编码很方便。把上面代码改成python,简单地用timedelta递增日期即可:

    from datetime import *
    num = list(map(int, input().split()))    # 输入100个数
    dt=datetime(2023,1,1)  
    ans = 0
    for i in range(365):       #365天   
        str_date = dt.strftime('%Y%m%d')   # 把日期改为 20230101格式
        k = 0
        for v in range(100):               # 在100个数中找这个日期
            if num[v] == int(str_date[k]):  k += 1
            if k >= 8:
                ans += 1
                break
        dt += timedelta(days=1) #继续检查下一个日期
    print(ans)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    B组-试题B-01串的熵

    蓝桥题库-01串的熵

    说明: 模拟题,简单。

    解析:

    直接模拟公式计算。

    #include
    using namespace std;
    
    int N = 23333333;
    double ans = 11625907.5798;
    double eps=1e-4;      //eps:误差
    int main(){
        for(int v=0;v<=N/2;v++){ //v是0的个数,0比1少
            int u=N-v;           //u是1的个数,v是0的个数
            double res=-1.0*u*u/N*log2(1.0*u/N)-1.0*v*v/N*log2(1.0*v/N);
            if(fabs(res-ans)<eps){  //res和ans相减小于误差,认为相等
                cout<<v;      //找到了v
                break;
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    C组-试题A-求和

    蓝桥题库-求和

    说明: 模拟,简单题。

    解析:

    极简单的题目,按数列求和公式计算。用Python写很简单。

    n = 20230408
    print(n * (n + 1) // 2)
    
    • 1
    • 2

    如果用C语言,需要考虑这是不是高精度问题,因为结果可能太大。如果定义长整型long long sum,是否会因为太大溢出?

    C组-试题B-工作时长

    蓝桥题库-工作时长

    说明: 模拟题,日期问题。

    解析:

    日期问题,简直是Python的绝配。下面用python来写:

    from datetime import datetime
    import sys
    
    # 读取时间记录
    time_str_list = []
    while True:            # 注意:输入有多组数据,没有明确的终止  
        inp = input()      # 读一行
        if not inp:   break          # 这行为空,输入结束
        time_str_list.append(inp)
    # 将字符串转换为datetime类型并放入列表中
    time_list = [datetime.strptime(t, '%Y-%m-%d %H:%M:%S') for t in time_str_list]
    # 对列表进行排序
    time_list.sort()
    sum = 0
    for i in range(len(time_str_list)//2):    
        seconds = time_list[2*i+1] - time_list[2*i]
        sum += seconds.total_seconds()
    print('%.0f' % sum)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这里是蓝桥的题解,也很好。方法是把每个时间都转成与2022-01-01 00:00:00的差,后面的排序和计算就方便了。

    #include
    
    using namespace std;
    int year, month, day, h, m, s;
    vector<int> days = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    vector<int> v;
    
    int main() {
        // 将输入时间换算成距离 `2022-01-01 00:00:00` 的秒数
        while (scanf("%d-%d-%d %d:%d:%d", &year, &month, &day, &h, &m, &s) == 6) {
            int sum = 0;
            for (int i = 1; i < month; ++i) {
                sum += days[i];
            }
            sum += day;
            sum = sum * 24 + h;
            sum = sum * 60 + m;
            sum = sum * 60 + s;
            v.push_back(sum);
        }
        // 将换算成秒数后的时间按升序排序
        sort(v.begin(), v.end());
        int ans = 0;
        // 相邻的每对时间,即为一次上班和下班的打卡记录。求每对的时间差再求和,就是小蓝2022年度的工作时长
        for (int i = 0; i < v.size(); i += 2) {
            ans += v[i + 1] - v[i];
        }
        cout << ans;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    G组-试题A-工作时长

    重复题

    G组-试题B-与或异或

    蓝桥题库-与或异或

    说明: 搜索,几乎只能用DFS。

    解析:

    这是典型的搜索题,把所有可能的情况搜一遍,用DFS编程。

    #include
    using namespace std;
    int op[11];
    int a[5][5];
    int ans;
    inline int OP(int a, int b, int c){
        if(c == 1)return a | b;
        if(c == 2)return a & b;
        return a ^ b;
    }
    void dfs(int n){
        if(n == 10){
            int c = 0;
            a[0][0] = 1, a[0][1] = 0, a[0][2] = 1, a[0][3] = 0, a[0][4] = 1;
            for(int i = 1; i <= 4; i++){
                for(int j = 0; j <= 4 - i; j++){
                    a[i][j] = OP(a[i-1][j], a[i-1][j+1], op[c++]);
                }
            }
            if(a[4][0])ans++;
            return;
        }
        for(int i = 1; i <= 3; i++){
            op[n] = i;
            dfs(n + 1);
        }
    }
    
    int main(){
        dfs(0);
        cout<<ans<<endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3.2 Java语言组

    蓝桥题库-特殊日期

    说明: 模拟题,日期问题。

    解析:

    除了检查每个日期,似乎没有更巧妙的办法。下面是java代码。运行时间约5秒。

    import java.util.*;
    public class Main {
        static int[] d1 = new int[] {31,28,31,30,31,30,31,31,30,31,30,31};
        static int[] d2 = new int[] {31,29,31,30,31,30,31,31,30,31,30,31};  //闰年定义
        public static void main(String[] args) {
            //闰年 和 平年
            int res = 0;
            for(int i = 2000;i <= 1999999;i ++)  {
                if((i % 4) == 0) {
                    if((i % 100) == 0 && (i % 400) == 0) {//闰年若为100的倍数 则应为400倍数
                           for(int j = 1;j <= 12;j ++)   //1月~12月
                             for(int k = 1;k <= d2[j -1];k ++)  //遍历该月日期
                                if((i % j) == 0 && ((i % k) == 0))//如果yy 能整除mm 和dd
                                     res ++;
                    }
                    else if((i % 100) != 0) {    //闰年若不为100的倍数 则为4倍数
                        for(int j = 1;j <= 12;j ++)     //1月~12月
                            for(int k = 1;k <= d2[j -1];k ++) //遍历该月日期
                                if((i % j) == 0 && ((i % k) == 0))
                                     res ++;
                    }
                    else {           //平年
                        for(int j = 1;j <= 12;j ++)  //1月~12月
                            for(int k = 1;k <= d1[j -1];k ++)   //遍历该月日期
                                if((i % j) == 0 && ((i % k) == 0))
                                     res ++;
                    }
                }
                else {//平年
                    for(int j = 1;j <= 12;j ++)
                        for(int k = 1;k <= d1[j -1];k ++)  //遍历该月日期
                            if((i % j) == 0 && ((i % k) == 0))
                                 res ++;
                }
            }
            res += 1;    //2000000 1 1
            System.out.println(res);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    A组-试题B-与或异或

    重复题

    B组-试题A-阶乘求和

    蓝桥题库-阶乘求和

    说明: 简单模拟题。

    解析:

    要算到202320232023的阶乘是不可能的。容易发现40!的末尾已经有9个0了,对阶乘的和S的末9位不再有影响。所以只需要算到39的阶乘就够了。就考核这一点。
    因为数字很大,可以一边计算一边对 1 0 9 10^9 109 取模。

    public class Main {
     
        public static void main(String ...args) { new Main().run(); }
     
        void run() {
            long ans = 0, fac = 1;
            for (int i = 1; i < 40; ++i) {
                fac = i * fac % 1000000000;
                ans = (ans + fac) % 1000000000;
            }
            System.out.println(ans);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    B组-试题B-幸运数字

    蓝桥题库-幸运数字

    ** **模拟题,数制转换。

    解析:

    这种题还是用Python处理比较简单。运行时间约10秒。

    a = "0123456789abcdef"
    cnt = 0
    i = 1
    while 1:
        y = eval("+".join(list(str(i))))
        b = eval("+".join(bin(i)[2:]))         # 二进制
        o = eval("+".join(oct(i)[2:]))         # 八进制
        h = 0
        for c in hex(i)[2:]:  h += a.index(c)  # 转为十六进制:        
        if i % y == 0 and i % b == 0 and i % o == 0 and i % h ==0:
            cnt += 1
            if cnt == 2023:
                print(i)
                break
        i += 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    C组-试题A-求和

    重复题

    C组-试题B-分糖果

    蓝桥题库-分糖果
    说明: DFS搜索题,请看官方题解

    G组-试题A-特殊日期

    重复题

    G组-试题B-与或亦或

    重复题

    3.3 Python语言组

    A组-试题A-特殊日期

    重复题

    A组-试题B-分糖果

    重复题

    B组-试题A-2023

    蓝桥题库-2023

    说明: 暴力法。

    解析:

    填空题可以用最简单暴力的方法,逐个搜’2023‘的每个字符在数字x里面有没有。就是运行时间比较长,约5分钟。

    cnt = 0
    s = '2023'
    def check(x):
        x = str(x);
        pos = 0
        for j in range(len(x)):    #逐个搜2023的每个字符在x里面有没有
            if x[j] == s[pos]:    pos += 1
            if pos == 4:          return True
        return False
    for i in range(12345678,98765432+1):
        if not check(i):   cnt += 1
    print(cnt)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    B组-试题B-硬币兑换

    蓝桥题库-硬币兑换

    说明: 思维题,参考蓝桥官网解析

    sum = 0
    for i in range(2024,4046):     #i是要凑的数字
        one_num = i - 2023
        last_num = i // 2
        if i % 2 == 0:                #偶数
            sum_1 = 0
            for j in range(one_num,last_num):  sum_1+=j
            sum_1 += last_num//2
            if sum_1 > sum:   sum=sum_1
        else:                      #奇数
            sum_2 = 0
            for j in range(one_num,last_num+1): sum_2+=j
            if sum_2 > sum:   sum=sum_2
    print(sum)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    C组-试题A-求和

    重复题

    C组-试题B-分糖果

    重复题

    G组-试题A-工作时长

    重复题

    G组-试题B-分糖果

    重复题

  • 相关阅读:
    【Redis】基于Redis6的数据类型以及相关命令、应用场景整理
    【银角大王——Django课程Day1】
    求教Jquery的Ajax事件
    Java elasticsearch scroll模板实现
    vue3组合式API实现父组件触发子组件中的方法 | vue3中ref的用法 | defineExpose的使用场景
    如何部署一个高可用高并发的电商平台
    二开版视频CMS完整运营源码/新版漂亮APP手机模板/集成员分销功能等
    阿里旗下语雀宕机近10小时 企业关键业务如何避免被“云”拖累
    [Chipscope 16-213] The debug port ‘dbg_hub/clk‘ has 1 unconnected channels 解决
    C语言学生综合测评系统
  • 原文地址:https://blog.csdn.net/samsara_of_ice/article/details/134202175