这里写目录标题
- 例题引入
- 题目分析
- 解题方法
- 1.暴力求解
- 2.求n的所有的因子
- foreach循环
- 3.利用 set集合
- 参考文章
例题引入
题目分析
- n个都是 V=1 的小正方体---》去拼成一个大的长方体---》满足n=L×W×H
- 也就是,在小于等于n的所有数中,任取3个数(可重复),这仨数的乘积等于n
- 然后,把这仨数全排列了,加到总方案数上。
解题方法
1.暴力求解
我第一想法就是直接暴力循环,但是n给的太大了
这方法pass掉
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
//太太太慢了!!!
long n = 2021041820210418L;
long count = 0L;
for(long i=1;i<=2021041820210418L;i++){
for(long j=1;j<=2021041820210418L;j++){
for(long k=1;k<=2021041820210418L;k++){
if(i*j*k == n){
count += 1;
}
}
}
}
System.out.print(count);
}
}
2.求n的所有的因子
既然暴力循环所有1到n的数不行,那按照题意,这仨数一定是n的因子
==》想到,能不能把所有的因子存到一起,然后只循环这些因子?
需要注意的是:在二分时,有一种特殊情况,使得存值会有个重复的
eg. n=4时
2*2=4
如果没有if(x != i) { //把 n = Math.sqrt(n) * Math.sqrt(n)情况排除掉
list.add(x);
}
那list中,就会存两个2---》存值重复
//先计算出2021041820210418的所有因子--》循环判断这些因子即可
long n = 2021041820210418L;
ArrayList<Long> list = new ArrayList<>();
//二分
for(Long i=1L; i<=Math.sqrt(n);i++) {
//能整除就加到list集合中
if(n%i == 0) {
list.add(i);
//再把大于sqrt(n)的 和i成对的因子也加到list集合中
long x = n/i;
if(x != i) { //把 n = Math.sqrt(n) * Math.sqrt(n)情况排除掉
list.add(x);
}
}
}
//这里发现传统的for循环,写这玩应太麻烦了
//学了一下foreach,语法在代码下面
long count = 0L;
for(long i : list) {
for(long j : list) {
for(long k : list) {
if(i*j*k == n) {
count++;
}
}
}
}
System.out.println(count);
foreach循环
for(element_type element : collection){
//循环体
}
-
element_type就是集合或数组中元素的类型
-
element 表示每次循环迭代时访问的元素
-
collection:表示要遍历的数组或集合
-
举个例子
eg. 遍历数组a int[] a = new int[n]; //用for循环就是: for(int i=0;i<n;i++){...} //用foreach就是: for(int i : a){...}
-
foreach的优缺点
- 【优点】
- 语法简洁:代码量少啊
- 避免了索引越界的错误:打代码的时候经常会遇见java.lang.ArrayIndexOutOfBoundsException这个错误,就是数组越界了。而foreach就避免了这种错误,它会自动处理集合或数组的边界情况。
- 【缺点】
- for可以动态修改遍历的范围,foreach不行
- 无法获取当前元素的索引:for就是利用的这种索引机制,才会有ArrayIndexOutOfBoundsException这个常见的报错。但同时,这也是foreach的缺点,foreach无法直接访问当前元素的索引,需要通过其他方式解决。
- 【优点】
3.利用 set集合
既然要单独解决元素重复的问题
那提到重复,就不得不提到Set集合了
它压根不会存重复的元素
long n = 2021041820210418L;
HashSet<Long> set = new HashSet<>();
for(long i=1L;i<=Math.sqrt(n);i++) {
if(n%i == 0) {
set.add(i);
long x = n/i;
set.add(x);
}
}
long count = 0L;
for(long i : set) {
for(long j : set) {
for(long k : set) {
if(i*j*k == n) {
count++;
}
}
}
}
System.out.println(count);
参考文章
- 求一个数的所有因子(约数)