C语言练习题目(五)----卡片

一、题目要求 

 

二、解题思路

理解题目后简略的来说是:

1、有0~9 这十种卡片,每种卡片有2021张

2、现需要用这些卡片拼数字,从1开始按顺序一直往下拼,用过的卡片不能重复再用,拼到拼不了为止

3、让我们用编程来计算能拼到多少

首先是10种卡片,每种卡片2021个数量,我想到的是用一维数组解决问题

创建一个10位的整型数组a,下标0~9的内容 分别代表 0~9卡片的数量。

                 例如a[5]=1564 代表 卡片51564张

 初始化让所有卡片初值都为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;
}

-----------------------------------------------------------------------------------

码题不易,跪求点赞!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值