牛客链接
题目
一个正整数可以分解成一个或多个数组的积。例如36=223*3,即包含2和3两个因子。NowCoder最近在研究因子个数的分布规律,现在给出一系列正整数,他希望你开发一个程序输出每个正整数的因子个数。
输入描述
输入包括多组数据。
每组数据仅有一个整数n (2≤n≤100000)。
输出描述
对应每个整数,输出其因子个数,每个结果占一行。
解题思路
思路1
第一个想到的算法是从i = 2开始循环,用输入的数据num除以 i ,除数用set保存,如果没出现过,则进行count++,一直到num == 1退出循环,直接输出count。
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int num = sc.nextInt();
int count = 0;
int i = 2;
HashSet<Integer> hashSet = new HashSet();
while (num != 1) {
if (num % i == 0) {
if (!hashSet.contains(i)) {
count++;
hashSet.add(i);
}
num = num/i;
}else{
i++;
}
}
System.out.println(count);
}
}
}
这种算法实现后会超时,问题就在于当n的某个因子为极大的质数时候或者n本身就是极大的质数时候,i便要从2一直一个试到那个极大的质数,这样便会耗费大量时间。
思路2
可以借鉴查看质数时所用的sqrt方法,将for循环放在外部。用conutAdd来记录是否有 i 这个因数,从 i = 2 时开始,小于 sqrt (num) 结束,如果满足num % i == 0 则一直进入循环,countAdd值保持不变为1,直到 i 这个因数被除尽为止退出循环让num = num / i,如果 i 不是因数则继续for循环让 i++继续找下一个不同的因数,直到num == 1时,退出循环直接break掉, 那如果退出循环后num不为1,就说明num是一个质数,此时让count+1,输出最终count结果。
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int num = sc.nextInt();
int count = 0;
for (int i = 2;i < Math.sqrt(num);i++) {
int countadd = 0;
while (num % i == 0) {
countadd = 1;
num = num/i;
}
count +=countadd;
if (num == 1) break;
}
if (num!=1) count++;
System.out.println(count);
}
}
}