目录
题目链接:13.卡片 - 蓝桥云课 (lanqiao.cn)
题目链接:13.卡片 - 蓝桥云课 (lanqiao.cn)
题目描述
小蓝有很多数字卡片,每张卡片上都是数字 0 到 9.
小蓝准备用这些卡片来拼一些数,他想从 1开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。
小蓝想知道自己能从 1拼到多少。
例如,当小蓝有 30 张卡片,其中 0到9各 3 张,则小蓝可以拼出 1 到 10,但是拼 11 时卡片 1 已经只有一张了,不够拼出 11。现在小蓝手里有 0 到 9 的卡片各 2021 张,共 20210 张,请问小蓝可以从 1 拼到多少?
提示:建议使用计算机编程解决问题
思路
今天心情一般,就不整活了,严肃一点。
这段代码的目标是计算在有限量的0-9数字卡片的条件下,可以拼凑出来的连续正整数的最大值。
主要逻辑如下:
-
直接在主程序
main
中定义了一个数组nums
,用于存储不同数字卡片的剩余数量。数组下标0-9分别对应卡片0-9的剩余数量,而下标10对应所有卡片的总剩余数量。 -
进入一个无限循环,每个循环表示尝试拼出一个新的数字
p
。它调用chooseYourCard(p, nums)
函数,如果函数返回true
,则说明卡片不足,不能拼出新数字,因此跳出循环。 -
chooseYourCard
函数中,它首先检查是否还有卡片剩余,如果没有,立即返回true
。接下来,它对数字p
进行循环,不断取p
的最低位的数字(通过p%10
得到),然后在arr
数组中对应的卡片数量减一。如果某个卡片已经用完(数量为0),就设置标志flag=true
。最后,更新p
为去掉最低位的新数字(通过p/10
得到)。 -
如果所有卡片都有剩余,那么就可以成功拼出数字
p
,然后p
加一,继续尝试拼下一个数字。否则,循环结束,打印出能拼出的最大数字p
。
此代码的时间复杂度为O(n),其中n为可拼出的数字的最大值。因为每个数字都被逐位处理一次。空间复杂度为O(1),因为我们只使用了固定大小的存储空间。
代码实现
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static int p = 1;
public static void main(String[] args) {
// 卡片的面值为 0 - 9
// 一共20210张卡片,0 - 9各2021
// 先定义出一个数组,用于存储卡片的数量
// 0 - 9索引分别对应每个卡片的剩余数量, 10 索引对应全部卡片的剩余数量
int[] nums = new int[] {2021,2021,2021,2021,2021,2021,2021,2021,2021,2021,20210};
// 判断当前数字需要花费什么卡片,分别多少张,在数组中减去对应的数量
while (true) {
boolean flag = chooseYourCard(p, nums);
if (flag) {
break;
}
p++;
}
System.out.println(p);
}
/**
* 该方法用于判断当前数字都需要什么卡片,并同时修改卡片的剩余数量
* @param p 当前卡片的数字
* @param arr 卡片数组的剩余量
*/
public static boolean chooseYourCard(int p, int[] arr) {
// 用于判断是否花完了全部卡片或者是某一种卡片
boolean flag = false;
if (arr[10] == 0) {
return true;
}
while (p != 0) {
// 取最后一位
int card = p % 10;
if (arr[card] > 0) {
arr[card]--;
}
if (arr[card] == 0) {
flag = true;
}
// 将p的最后一位去除
p = p / 10;
}
return flag;
}
}
总结
就这。。。
收徒