完数
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11766 Accepted Submission(s): 4082
Problem Description 完数的定义:如果一个大于1的正整数的所有因子之和等于它的本身,则称这个数是完数,比如6,28都是完数:6=1+2+3;28=1+2+4+7+14。
本题的任务是判断两个正整数之间完数的个数。
Input 输入数据包含多行,第一行是一个正整数n,表示测试实例的个数,然后就是n个测试实例,每个实例占一行,由两个正整数num1和num2组成,(1<num1,num2<10000) 。
Output 对于每组测试数据,请输出num1和num2之间(包括num1和num2)存在的完数个数。
Sample Input 2 2 5 5 7
Sample Output 0 1
Author lcy
Source
杭电ACM集训队训练赛(IV)
Recommend Ignatius.L
虽然我做的比较复杂,好像直接枚举所有的1~n-1的数来判断约数都可以过的。
我练习下合数分解,然后求的所有因子的和
/* HDU 1406 */ #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; //****************************************** //素数筛选和合数分解 const int MAXN=10000; int prime[MAXN+1]; void getPrime() { memset(prime,0,sizeof(prime)); for(int i=2;i<=MAXN;i++) { if(!prime[i])prime[++prime[0]]=i; for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++) { prime[prime[j]*i]=1; if(i%prime[j]==0) break; } } } long long factor[100][2]; int fatCnt; int getFactors(long long x) { fatCnt=0; long long tmp=x; for(int i=1;prime[i]<=tmp/prime[i];i++) { factor[fatCnt][1]=0; if(tmp%prime[i]==0) { factor[fatCnt][0]=prime[i]; while(tmp%prime[i]==0) { factor[fatCnt][1]++; tmp/=prime[i]; } fatCnt++; } } if(tmp!=1) { factor[fatCnt][0]=tmp; factor[fatCnt++][1]=1; } return fatCnt; } //****************************************** long long pow_m(long long a,long long n)//快速幂运算 { long long res=1; long long tmp=a; while(n) { if(n&1)res*=tmp; n>>=1; tmp*=tmp; } return res; } long long sum(long long p,long long n)//计算1+p+p^2+````+p^n { if(p==0)return 0; if(n==0)return 1; if(n&1)//奇数 { return ((1+pow_m(p,n/2+1))*sum(p,n/2)); } else return (1+pow_m(p,n/2+1))*sum(p,n/2-1)+pow_m(p,n/2); } bool judge(int n) { getFactors(n); int temp=1; for(int i=0;i<fatCnt;i++) temp*=sum(factor[i][0],factor[i][1]); if(2*n==temp)return true; else return false; } bool a[10010]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); getPrime(); for(int i=1;i<=10000;i++)a[i]=judge(i); int m,n; int T; scanf("%d",&T); while(T--) { scanf("%d%d",&m,&n); if(m>n)swap(m,n); int ans=0; for(int i=m;i<=n;i++) if(a[i])ans++; printf("%d\n",ans); } return 0; }