【蓝桥杯基础题】2021年省赛填空题—卡片

简介: 【蓝桥杯基础题】2021年省赛填空题—卡片

一、题目背景

本题为2021年省赛填空题

  • C/C++A组第1题
  • C/C++B组第2题
  • Java B组第2题
  • Java B组第3题
  • Python组第1题

二、题目描述

小蓝有很多数字卡片,每张卡片上都是数字 0 到 9。
小蓝准备用这些卡片来拼一些数,他想从 1 开始拼出正整数,每拼一个就保存起来,卡片就不能用来拼其它数了。小蓝想知道自己能从 1 拼到多少。例如,当小蓝有 30 张卡片,其中 0到9各3 张,则小蓝可以拼出 1到 10。但是拼 11 时卡片 1 已经只有一张了,不够拼出 11。

现在小蓝手里有 0到9 的卡片各 2021 张,共 20210 张,请问小蓝可以从 1拼到多少?
提示:建议使用计算机编程解决问题。

三、题目分析

本题是一道非常典型的基础枚举题。想求出最多拼到多少,那就从1开始一直往后枚举,枚举的过程中检查这个数是不是符合条件,如果符合卡片条件就继续枚举,直到不符合条件为止(卡片不够了)。
所以这道题的核心就转到了 如何检查 上。

1.检查思路

我们可以申请一个下标分别从0到9的数组,对应卡片从0~9,让每一个数组的值都为卡牌的总数量大小:2021
然后通过取余的方式,将每一位对应的数字求出来,然后看看这些对应位置的数的数量是不是符合卡牌的数量。

取余求每个位置的数 :
例如: 求 189的每一位数的大小
个位: 189%10 = 9
十位: (189/10)%10 = 8
百位: (189/10/10)%10 = 1

下面我用C语言写一下这段起检查作用的函数

#include<stdio.h>
int card[10];                 // (1)
int check(int num)            // (2)
{
    while (num)
    {
        int a = num % 10;    //(3)
        if (card[a] > 0)    //(4)
            card[a]--;        //(5)
        else                
            return 0;        //(6)
        num = num / 10;        //(7)
    }
    return 1;                
}
  • (1)申请下标分别从0到9的数组,用来存卡片
  • (2)num表示需要检查的数
  • (3)求每一位的数是多少
  • (4)判断这个数对应的卡牌还有没有
  • (5)如果有,就符合要求,但是用过了这张卡牌所以减一
  • (6)如果没有,就不符合要求
  • (7)改变位数(将百位变为十位,十位变为个位......)

2.思路优化

上面的思路,其实已经能够完成检查的任务,但是如果仔细想想,其实枚举是从1开始,那么消耗卡片1的数量是最多的。卡片1的数量是最先小于0,所以我们只需要检查卡片1的数量就可以了。

下面我用C语言写一下优化后的函数

#include<stdio.h>
int card[10];  
int check(int num)
{
    while (num)
    {
        int a = num % 10;        //(1)
        if (a == 1)                //(2)
            if (card[1] == 0)    //(3)
                return 0;
            else
                card[1]--;        //(4)
        num = num / 10;            //(5)
    }
    return 1;
}
  • (1)求每一位的数是多少
  • (2)如果这一位是1
  • (3)如果卡牌1的数量等于0,结束检查
  • (4)如果不为0,卡牌1的数量减一
  • (5)改变位数(将百位变为十位,十位变为个位......)

四、代码汇总

1.C语言代码

C语言里面没有bool类型,但是C语言中0代表假,非0代表真。

#include<stdio.h>
int card[10];  
int check(int num)
{
    while (num)
    {
        int a = num % 10;
        if (a == 1)
            if (card[1] == 0)
                return 0;
            else
                card[1]--;
        num = num / 10;
    }
    return 1;
}
int main()
{
    for (int i = 0; i <= 9; i++)
        card[i] = 2021;               //(1)
    for (int i = 1;check(i); i++)     //(2)
    {
        printf("%d\n", i );         //(3)
    }
    return 0;
}

(1)循环,让每个卡牌的数量都为2021个
(2)逐个枚举检查
(3)输出符合的正确的结果

2. C++代码

C++代码和C语言代码大致差不多,不同的是C++里面有bool类型

当然printf也可也用c++里面的cout代替

cout不需要记太多的占位符,更加方便。

#include<iostream>
using namespace std;
int card[10];  
bool check(int num)
{
    while (num)
    {
        int a = num % 10;
        if (a == 1)
            if (card[1] == 0)
                return false;
            else
                card[1]--;
        num = num / 10;
    }
    return true;
}
int main()
{
    for (int i = 0; i <= 9; i++)
    {
        card[i] = 2021;
    }
    for (int i = 1;check(i); i++)
    {
        cout << i << endl;
    }
    return 0;
}

3.运行结果

以下为代码的运行结果。

在这里插入图片描述

故最终答案为:3181

五、总结

1.枚举思想

枚举就是是从问题所有可能的解的集合中一一枚举出各种元素。

并且用题目中给定的检验条件判定哪些元素是错误的,哪些是正确的。

2.取余求位数

取余求各个位数是常用的基本功。
不管是几位数个位数都可以直接使用 数 % 10 来取余数获得
至于获取十位数,百位数,只需要处于10或100再进行取余即可获得。

相关文章
|
6月前
蓝桥杯真题代码记录(卡片
蓝桥杯真题代码记录(卡片
50 0
|
存储
【蓝桥杯冲刺】蓝桥杯12届省赛C++b组真题-填空题
【蓝桥杯冲刺】蓝桥杯12届省赛C++b组真题-填空题
102 1
【蓝桥杯冲刺】蓝桥杯11届省赛C++b组真题-填空题
【蓝桥杯冲刺】蓝桥杯11届省赛C++b组真题-填空题
126 0
蓝桥杯系列5——填空题练习
蓝桥杯系列5——填空题练习
61 0
|
算法 Python
【Python 百练成钢】蓝桥杯填空题
【Python 百练成钢】蓝桥杯填空题
蓝桥杯-卡片-Java
消耗完卡片1 创建哈希表HashMap 从1遍历到任意大的数(尽量大一点),直到【键】1的【值】为2021时,退出循环
|
测试技术
蓝桥杯之找素数(填空题+编程题)
蓝桥杯之找素数(填空题+编程题)
157 0
|
Java C语言 C++
【蓝桥杯基础题】2020年省赛填空题—既约分数
【蓝桥杯基础题】2020年省赛填空题—既约分数
【蓝桥杯基础题】2020年省赛填空题—既约分数
|
Java 测试技术 C语言
【蓝桥杯基础题】2020年省赛填空题—回文日期
【蓝桥杯基础题】2020年省赛填空题—回文日期
【蓝桥杯基础题】2020年省赛填空题—回文日期
|
Python
(蓝桥云课)「蓝桥杯赛前急救」简单填空题秒杀拿分技巧
(蓝桥云课)「蓝桥杯赛前急救」简单填空题秒杀拿分技巧
93 0