描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
数据范围: 1≤n≤2×109+14 1≤n≤2×109+14
输入描述:
输入一个整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。
示例1
输入:
180
输出:
2 2 3 3 5
思路:
质因数,最小从2开始,求质因数要把这个数分解到不能再分解为止,所以每次找到一个质因数,那就让原数字变成分解出质因数之后剩下的数字,并且再次从头找.
例如: 题目的示例数字180,从2开始,180可以整除2,所以第一个质因数就是2,分解出2之后180变为90,再找90 的质因数,第一个仍然是2,所以第二个质因数就是2,分解出2之后90变为45,再次从头找,现在第一个能整除的数字是3,所以第三个质因数就是3,分解出3之后剩余的数字就是15,以此类推,180最后分解成的质因数就是 2 2 3 3 5
这个思路是没有问题的,但是有这样一条用例:2000000014,这个数字在分解出第一个质因数2之后是1000000007,而规定的运行时间只有1s,不足以执行完这条用例,所以我们需要想别的办法.
我们可以在每一次寻找质因数之前判断一下,上一次剩下的数字是不是质数,如果是质数,它无法被除1和它本身之外的所有数字整除,所以这种情况就不需要去找它的质因数了,直接输出它本身就好.
现在我们再想一想,怎么样判断这个是数字是质数呢,从1遍历到这个数字本身,一一比较?那这个耗时和我们上面的写法是一样的,还是不能满足要求,
举个例子,比如这个数字是x,要判断它是不是质数,就是看能不能被1和它之外的数字整除.现在我们假设y是x的开方,也就是说y * y=x; 如果现在还有两个数字m n,m*n也等于x,如果m>y,那n必然小于y.所以要判断它是不是质数,我们不需要去遍历2到x,只需要遍历2到y即可,这样我们的遍历次数就可以大大降低了.
按照上面的例子,遍历1000000007,1秒内是执行不完的,那如果是它的开方呢,大约是30000多,这个遍历的数量降低了30000多倍,执行效率就可以大大降低了.
所以我们只需要在每次找质因数的时候判断剩下的数字是不是质数,下面找质因数的方法还是保持不变的.
解答:
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
int num = in.nextInt();
for (int i = 2; i <= num; i++) {
if (isper(num)) {
System.out.print(num + "");
// 如果这个数字是质数,那这个数字也无法再被分解下去了,所以之后的遍历毫无意义,直接break即可;
break;
}
if (num % i == 0) {
num /= i;
System.out.print(i + " ");
i = 1;
}
}
}
// 判断一个数字是不是质数
static boolean isper(int num) {
for (int i = 2; i * i <= num; i++) {
if (num % i == 0)
return false;
}
return true;
}
}