hdu 1460 完数
注意:num1和num2的大小未知,需比较!
有两种方法:
法一:素数打印+素数分解(求因数和公式)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 int p[10005];//记录包括自身的完数个数 9 bool vis[10005]; 10 int prime[1229+1];//如何估算比n小的素数的个数?? 提前打印即可,小于10000共1229个素数 11 void print_prime(){ 12 memset(vis,false,sizeof(vis)); 13 int i=2; 14 int index=0; 15 for(;i<10000;i++){ 16 if(!vis[i]){ 17 prime[index++]=i; 18 } 19 for(int j=0;j<index&&prime[j]*i<10000;j++){ 20 vis[prime[j]*i]=true; 21 if(i%prime[j]==0){ 22 break; 23 } 24 } 25 } 26 } 27 int work(int n){ 28 int i=0,ret=1,total=1,temp=n; 29 for(;prime[i]*prime[i]<=n;i++){ 30 int sum=1; 31 int num=1; 32 while(n%prime[i]==0){ 33 num*=prime[i]; 34 n/=prime[i]; 35 sum+=num; 36 } 37 total*=sum; 38 } 39 if(n>1){ 40 total*=n+1; 41 } 42 return total-temp; 43 } 44 void get_p(){ 45 memset(p,0,sizeof(p)); 46 p[2]=0; 47 p[3]=0; 48 int i=4; 49 for(;i<10000;i++){ 50 if(i==work(i)){ 51 p[i]=p[i-1]+1; 52 } 53 else{ 54 p[i]=p[i-1]; 55 } 56 } 57 } 58 int main()//10000 59 { 60 int n; 61 cin>>n; 62 print_prime(); 63 get_p(); 64 //cout<<p[6]<<endl; 65 while(n--){ 66 int num1,num2; 67 cin>>num1>>num2; 68 if(num1>num2){ 69 num1=num1+num2; 70 num2=num1-num2; 71 num1=num1-num2; 72 } 73 cout<<p[num2]-p[num1-1]<<endl; 74 } 75 return 0; 76 }
法二:筛法
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 int main()//10000 9 { 10 int n; 11 cin>>n; 12 while(n--){ 13 int num1,num2; 14 cin>>num1>>num2; 15 if(num1>num2){ 16 num1=num1+num2; 17 num2=num1-num2; 18 num1=num1-num2; 19 } 20 int i=num1; 21 int num=0; 22 for(;i<=num2;i++){ 23 int j=2; 24 int sum=1; 25 for(;j<=i/2;j++){ 26 if(i%j==0){ 27 sum+=j; 28 } 29 } 30 if(sum==i){ 31 num++; 32 } 33 } 34 cout<<num<<endl; 35 } 36 return 0; 37 }