一、题目要求
二、解题思路
理解题目后简略的来说是:
1、有0~9 这十种卡片,每种卡片有2021张
2、现需要用这些卡片拼数字,从1开始按顺序一直往下拼,用过的卡片不能重复再用,拼到拼不了为止
3、让我们用编程来计算能拼到多少
首先是10种卡片,每种卡片2021个数量,我想到的是用一维数组解决问题。
创建一个10位的整型数组a,下标0~9的内容 分别代表 0~9卡片的数量。
例如a[5]=1564 代表 卡片5有1564张
初始化让所有卡片初值都为2021
然后用一个没有结束条件的for循环来输出从1到n的数字
因为不知道拼到数字几才算结束,所以n是未知的,for循环不能有第二表达式
这里的for主要作用是给我一个数字,并且这个数字是从1到n的
令j=i是因为我后面要把i这个数的每一位都提取出来,不能直接处理i,怕影响循环
在for中嵌套一个while循环,这个while循环主要作用是消耗卡片并重复获取这个数字的每一位
j就是要处理的数字,而max代表的是j这个数字的最后一位,例如j=1548,max=8
找到最后一位后要将最后一位的卡片消耗,a[max]-=1
再令j=j/10,这一步是将j这个数字的最后一位去除。例如j=123,处理后j=12
若处理后j=0,则说明原来j为个位数,已经是这个数字的最后一个数。
例如我要处理123这个数,先处理3,再处理2,再处理1。处理完1的时候,j已经是个位,j/10就为0了,这也是跳出循环的依据。
当其中一个卡片用完了,不代表就该停止了,因为拼下一个数字可能不需要用到这个消耗完的卡片
所以if条件为a[max]==-1,只有当剩余数量为0的卡片再次被使用,才说明当前数字已经不能被拼出
三、实现代码
#include <stdio.h>
int main(){
int a[10],i,j,max=0;
//初始化数组,让每个数组内都存放整型常量2021
for(i=0;i<10;i++){
a[i]=2021;
}
//i为拼出来的数字,因为不知拼到哪个数字才用完卡片,所以i没有边界。去掉 条件表达式2
for(i=1;;i++){
j=i; //保留当前i的值给j,因为后面要对这个值进行运算,不能影响i
//条件循环,只有当j等于0,才退出循环。循环过程实现的是:把i这个数的每一位数字找到并在数组中减去对应的卡片数目
while(j!=0){
max=j%10;//max为j这个数的最后一位,例如j=156,则max=6.
a[max]-=1;//让max下标的数组数据减一,因为数组中存放的是卡片数目。这条语句是用掉一个卡片的语句
j=j/10;//j等于自身除以10,若j为个位数,则j除以10会等于0。j为个位数说明已经完成最后一位,可以跳出循环了
if(a[max]==-1) break;//若某个卡片用完了,则跳出循环
}
//跳出循环有两种可能,一是j=0了,二是某个卡片用完了(即a[max]==0),所以跳出循环后加多一个判断:若卡片用完,则再次跳出循环
if(a[max]==-1) break;
}
//j若等于0,则说明用完卡片的时候,最后一张卡片恰巧拼出来最后一个数字,说明
if(j==0) printf("%d\n",i);
else printf("%d\n",i-1);
return 0;
}