Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6628 Accepted Submission(s): 2160
1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 5 bool data[10000000]; 6 #define max 10000000 7 8 bool dep(int num) 9 { 10 int i; 11 for(i=2;i<sqrt(num);i++) 12 { 13 if(num%i==0) 14 return true; 15 } 16 return false; 17 } 18 19 int main() 20 { 21 int i,j; 22 int num; 23 int count; 24 int number; 25 memset(data,0,sizeof(data)); 26 for(i=2;i<=5000000;i++) 27 { 28 if(data[i]==0) 29 for(j=i+i;j<=10000000;j+=i) 30 data[j]=1; 31 } 32 while(~scanf("%d",&num)) 33 { 34 count=0; 35 for(i=0;i<num;i++) 36 { 37 scanf("%d",&number); 38 if(number>=max) 39 { 40 if(!dep(number)) 41 count++; 42 } 43 else if(!data[number]) 44 count++; 45 } 46 printf("%d\n",count); 47 } 48 return 0; 49 }
筛选法核心:
for(i=2;i<=5000000;i++)
{
if(data[i]==0)
for(j=i+i;j<=10000000;j+=i)
data[j]=1;
}
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 17449 Accepted Submission(s): 5198
1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 5 int data[500000]; 6 7 int main() 8 { 9 int n; 10 int num; 11 int result; 12 int temp; 13 int i,j; 14 int tip=0; 15 int p,q,r; 16 memset(data,0,sizeof(data)); 17 for(i=2;i<=250000;i++) 18 { //筛选法 19 if(data[i]==0) 20 for(j=i+i;j<=500000;j+=i) 21 data[j]=1; 22 } 23 while(~scanf("%d",&n)) 24 { 25 while(n--) 26 { 27 result=1; 28 scanf("%d",&num); 29 temp=num; 30 r=1; 31 for(i=2;i<=500000;i++) 32 { 33 q=1; 34 if(!data[i]) 35 { 36 p=1; 37 while(num%i==0) 38 { 39 p*=i; //公式 40 num/=i; 41 q+=p; 42 } 43 r*=q; 44 if(i>num) 45 break; 46 } 47 } 48 printf("%d\n",r-temp); 49 } 50 } 51 return 0; 52 } 53 54 /*#include<iostream> 55 #include<cmath> 56 using namespace std; 57 58 int count[50000]; 59 int flag[50000]; 60 int data[500000]; 61 62 int main() 63 { 64 int n; 65 int num; 66 int result; 67 int temp; 68 int i,j; 69 int tip=0; 70 memset(data,0,sizeof(data)); 71 for(i=2;i<=250000;i++) 72 { 73 if(data[i]==0) 74 for(j=i+i;j<=500000;j+=i) 75 data[j]=1; 76 } 77 while(~scanf("%d",&n)) 78 { 79 while(n--) 80 { 81 result=1; 82 scanf("%d",&num); 83 temp=num; 84 memset(count,0,sizeof(count)); 85 memset(flag,0,sizeof(flag)); 86 for(i=2;i<=500000;i++) 87 { 88 if(!data[i]) 89 { 90 while(num%i==0) 91 { 92 flag[i]=1; 93 count[i]++; 94 num/=i; 95 } 96 if(flag[i]) 97 result*=(pow(i,(count[i]+1))-1)/(i-1); //公式:超时 98 if(i>num) 99 break; 100 } 101 } 102 printf("%d\n",result-temp); 103 } 104 } 105 return 0; 106 } 107 */
纠结了有蛮久,刚开始没有用筛选法,而且后面的公式写的方法不对,导致了超时,提交了N次,命中率伤不起了。
看了下别人的解法,代码写的真整洁,真是自愧不如。
法一:筛选法。。。。。空间换时间
1 #include <iostream> 2 3 using namespace std; 4 5 int wife[500010] = {0}; 6 7 int main( ) 8 { 9 for( int i = 0; i < 500001; ++i ) 10 { 11 wife[i] = 1; 12 } 13 for( int i = 2; i < 500001; ++i ) 14 { 15 for( int j = 2; i * j < 500001; ++j ) 16 { 17 wife[i*j] += j; 18 } 19 } 20 int T; 21 cin >> T; 22 while( T-- ) 23 { 24 int N; 25 cin >> N; 26 cout << wife[N] << endl; 27 } 28 return 0; 29 }
法二:暴力
1 #include <iostream> 2 #include <cmath> 3 4 using namespace std; 5 6 int main( ) 7 { 8 int T; 9 cin >> T; 10 while( T-- ) 11 { 12 int N; 13 cin >> N; 14 int t = sqrt( N ); 15 int sum = 1; 16 for( int i = 2; i <= t; ++i ) 17 { 18 if( N % i == 0 ) 19 { 20 sum += i; 21 if( N / i != i ) 22 { 23 sum += N / i; 24 } 25 } 26 } 27 cout << sum << endl; 28 } 29 return 0; 30 }
约数的求和公式:
数360的约数有多少个?这些约数的和是多少?
【分析与解】 360分解质因数:360=2×2×2×3×3×5=23×32×5;
360的约数可以且只能是2a×3b×5c,(其中a,b,c均是整数,且a为0~3,6为0~2,c为0~1).
因为a、b、c的取值是相互独立的,由计数问题的乘法原理知,约数的个数为(3+1)×(2+1)×(1+1)=24.
我们先只改动关于质因数3的约数,可以是l,3,32,它们的和为(1+3+32),所以所有360约数的和为(1+3+32)×2y×5w;
我们再来确定关于质因数2的约数,可以是l,2,22,23,它们的和为(1+2+22+23),所以所有360约数的和为(1+3+32)×(1+2+22+23)×5w;
最后确定关于质因数5的约数,可以是1,5,它们的和为(1+5),所以所有360的约数的和为(1+3+32)×(1+2+22+23)×(1+5).
于是,我们计算出值:13×15×6=1170.
所以,360所有约数的和为1170.
评注:我们在本题中分析了约数个数、约数和的求法.下面我们给出一般结论:
I.一个合数的约数的个数是在严格分解质因数之后,将每个质因数的指数(次数)加1后
所得的乘积.如:1400严格分解质因数后为23×52×7,所以它的约数有(3+1)×(2+1)×(1+1)=4×3×2=24个.(包括1和它自身)
Ⅱ.约数的和是在严格分解质因数后,将M的每个质因数最高次幂的所有约数的和相乘所得到的积.如:21000=23×3×53×7,所以21000所有约数的和为(1+2+22+23)×(1+3)×(1+5+52+53)×(1+7)=74880.