题目描述(1)
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。
小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆L,W,H的货物,满足 n=L×W×H。
给定 n,请问有多少种堆放货物的方案满足要求。
例如,当 n=4 时,有以下 66 种方案:1×1×4、1×2×2、1×4×1、2×1×2、2×2×1、4×1×1。
请问,当n=20210418(注意有 16位数字)时,总共有多少种方案?
提示:建议使用计算机编程解决问题。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
运行限制
-
最大运行时间:1s
-
最大运行内存: 256M
解题结果
Java
import java.util.ArrayList;
public class Main {
public static void main(String args[]) {
//寻找给定数字 `num` 的因子,并利用这些因子组成所有可能的三个因子的组合,计算满足条件的组合数。首先,通过遍历1到`Math.sqrt(num)`,找到`num` 的所有因子,并将它们存储在 `arr` 数组中。然后,通过三层嵌套循环遍历 `arr` 数组中的所有可能组合,统计满足条件的组合数,最终输出结果。
//这种方法相对于直接使用三层嵌套循环遍历1到 `num`,大大减小了时间复杂度,因为它只需要遍历 `num` 的因子。这样的优化在处理大数值的情况下尤为显著,避免了无效的组合计算,提高了程序的效率。
long num = 2021041820210418l;
//如果直接赋值,计算机默认数字是int类型,会报错。所以要在后面加'l',转换为long类型
//定义一个ArrayList数组,存放num的因子
ArrayList<Long> arr = new ArrayList<>();
for ( long i = 1 ; i <= Math.sqrt(num) ; i++ ){
if ( num % i == 0 ){
arr.add(i); //如果能被整除,就放到arr数组中
//当i能被num整除的情况下,求出num关于i的另外一个除数n
//这样,for循环不需要从1遍历到num。可以通过较小的因子,求出另外一个较大的因子
long n = num / i;
//如果num = Math.sqrt(num)*Math.sqrt(num),那么由较小的因子求较大的因子时,会重复,要排除这种情况
if ( n != i ){
arr.add(n); //将较大的因子放入arr数组
}
}
}
int count = 0;
for ( long i : arr ){
for ( long j : arr ){
for ( long k : arr ){
if ( i * j * k == num ){
count++;
}
}
}
}
System.out.println(count);
}
}
题目描述(2)
小蓝认为如果一个数含有偶数个数位,并且前面一半的数位之和等于后面一半的数位之和,则这个数是他的幸运数字。例如 2314是一个幸运数字, 因为它有 4 个数位, 并且 2+3=1+4 。现在请你帮他计算从 1至 100000000 之间共有多少个不同的幸运数字。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
运行限制
语言 | 最大运行时间 | 最大运行内存 |
---|---|---|
C++ | 1s | 256M |
C | 1s | 256M |
Java | 2s | 256M |
Python3 | 3s | 256M |
PyPy3 | 3s | 256M |
Go | 3s | 256M |
JavaScript | 3s | 256M |
解题结果
Java
通过嵌套循环遍历从1到100000000之间的所有可能数字,检查每个数字是否满足幸运数字的条件。对于每个偶数位的数字,计算其前一半和后一半的数位之和,如果二者相等,则将该数字计入幸运数字的统计。最终输出统计结果,表示在给定范围内有多少个不同的幸运数字。这种方法的代价主要体现在遍历所有数字和对每个数字的数位计算上,时间复杂度较高。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int count = 0;
// 从1到100000000遍历所有可能的数字
for (int i = 1; i <= 100000000; i++) {
// 将数字转换为字符串以便处理每一位数
String numStr = String.valueOf(i);
int length = numStr.length();
// 如果数字的位数为偶数
if (length % 2 == 0) {
int sumFirstHalf = 0;
int sumSecondHalf = 0;
// 计算前一半和后一半的数位之和
for (int j = 0; j < length / 2; j++) {
sumFirstHalf += Character.getNumericValue(numStr.charAt(j));
sumSecondHalf += Character.getNumericValue(numStr.charAt(j + length / 2));
}
// 如果前一半和后一半的数位之和相等,则是幸运数字
if (sumFirstHalf == sumSecondHalf) {
count++;
}
}
}
// 输出结果
System.out.println(count);
scan.close();
}
}
通过使用一个二维数组 a
,其中 a[i][j]
表示有 i
位数位和为 j
的数字的个数,统计了1到9999的所有数字。然后,通过三层循环,遍历每个可能的位数和数字,计算满足条件的数字对的个数,并最终输出结果。具体而言,通过循环遍历位数 i
、数位和 j
,以及一个辅助变量 k
,统计满足条件的数字对的个数,将其累加到 ans
中。最终,输出 ans
表示满足条件的数字对的总数。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[][] a=new int[5][37];
int ans=0;
for(int i=1;i<=9999;i++){
String x=String.valueOf(i);
int sum=0;
for(int j=0;j<x.length();j++){
sum+=x.charAt(j)-'0';
}
a[x.length()][sum]++;
}
for(int i=1;i<5;i++)
for(int j=1;j<=9*i;j++)
for(int k=1;k<=i;k++){
ans+=a[i][j]*a[k][j];
}
System.out.println(ans);
}
}
题目描述(3)
请求出在 12345678(含)至 98765432(含)中,有多少个数中完全不包含 2023。
完全不包含 2023是指无论将这个数的哪些数位移除都不能得到 2023。例如 20322175,33220022都完全不包含 2023,而 20230415,20193213 则含有 2023(后者取第 1,2,6,8个数位)。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
运行限制
语言 | 最大运行时间 | 最大运行内存 |
---|---|---|
C++ | 1s | 256M |
C | 1s | 256M |
Java | 2s | 256M |
Python3 | 3s | 256M |
PyPy3 | 3s | 256M |
Go | 3s | 256M |
JavaScript | 3s | 256M |
解题结果
Java
public class Main {
public static void main(String[] args) {
// 用于比较的数组
int[] a = {2, 0, 2, 3};
int cnt = 0;
// 循环范围修改为符合Java的语法规范
for (int i = 12345678; i <= 98765432; i++) {
if (!is2023Number(i, a)) {
cnt++;
}
}
System.out.println(cnt);
}
// 重写比较函数
static boolean is2023Number(int x, int[] a) {
int[] data = new int[8];
int idx = 7;
// 把每个整数变成数组格式
while (x > 0) {
data[idx--] = x % 10;
x /= 10;
}
// 判断是否存在2023
int k = 0;
for (int i = 0; i <= 7; i++) {
if (a[k] == data[i]) {
k++;
}
if (k > 3) {
break;
}
}
return k == 4;
}
}