华为机试在线训练之质数因子
题目描述:
功能:输入一个正整数,按照从小到大的顺序输出它的所有质数的因子(如180的质数因子为2 2 3 3 5 )
最后一个数后面也要有空格
解答:
傻了这题,根本不用考虑是否是质数的问题。
我考虑到如果除4除6这种非质数怎么处理。但实际上被除数从2开始往上递增,如果能整除就不增加,看除法的结果还能不能继续整除。
如180/2=90,2不动
90/2=45,2不动
45/2不行,2+1=3
45/3=15,3不动
。。。。以此类推
这样假设被除数加到了8,那么一定不能被8整除,毕竟8有因数2。如果能整除8,那么之前就会多除几次2,被除数不会直接增加到8了。
代码1:
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 long num; 7 8 while(cin >> num){ 9 if(num == 1){ 10 cout << num << endl; 11 continue; 12 } 13 14 for(int i = 2; i <= num; ++i){ 15 if(num%i == 0){ 16 num = num/i; 17 cout << i << " "; 18 i--;//遇到一个质数,那么该质数可能会被整除多次 19 } 20 } 21 cout << endl; 22 } 23 24 return 0; 25 }
还可以改进一点复杂度,其中被除数的for循环可以到sqrt(num),即num的算数平方根为止。因为如果被除数i增加到了根号num,那么说明num已经不可能有小于根号num的因数了。所以根号num乘根号num已经等于num了。一旦i大于根号num,则i^2已经一定大于num了,那么num也就不再可能有其他因数了(小于num自己的因数)。
时间复杂度O(N)改到O(LOGN)
代码2:
1 #include <iostream> 2 #include <math.h> 3 using namespace std; 4 5 int main() 6 { 7 long num; 8 9 while(cin >> num){ 10 if(num == 1){ 11 cout << num << endl; 12 continue; 13 } 14 15 for(int i = 2; i <= sqrt(num); ++i){ 16 if(num%i == 0){ 17 num = num/i; 18 cout << i << " "; 19 i--;//遇到一个质数,那么该质数可能会被整除多次 20 } 21 } 22 if(num>1){ 23 cout<<num<<" "; 24 } 25 cout << endl; 26 } 27 28 return 0; 29 }
进击的小🐴农