UVa 294 - Divisors 解题报告 c语言实现 素数筛法
1.题目大意:
输入两个整数L、H其中($1≤L≤H≤10^9,H−L≤10000$),统计[L,H]区间上正约数最多的那个数P(如有多个,取最小值)以及P的正约数的个数D。
2.原理:
对于任意的一个正整数N,若有$N=p_1^{e1}p^{e2}_2...p^{er}_r$ 且$p_1、p_2...p_r$都为素数,则有N的因数个数为$(e1+1)(e2+1)...(er+1)$。
3.范围确定
关于对maxn的确定,由$1≤L≤H≤10^9$可知:对 $10^9$ 开根号,大概估算一下,将maxn取32000。
4.思路
考虑先素数筛法打表得出32000以内所有素数,然后把因数个数求出来,若大于之前出现过的最大因子数,则修改;反之,不变。
5.代码:
#include"stdio.h" #define maxn 32000 int prime[maxn],origin[maxn]; int getfactor(int* prime ,int i)// 求出因数个数 { int sum=1,count; for(int j=1; j<prime[0]&&i!=1; j++) if(i%prime[j]==0) { count=1; while(i%prime[j]==0) { count++; i/=prime[j]; } sum*=count; } return sum; } int main() { /* 利用素数筛法得出32000以内所有素数 存入prime数组中 */ for(int i=0; i<maxn; i++) origin[i]=1; for(int i=2; i<maxn; i++) if(origin[i]) for(int j=2*i; j<maxn; j+=i) origin[j]=0; prime[0]=0; for(int i=2; i<maxn; i++) if(origin[i]) prime[++prime[0]]=i; // 用prime[0]表示素数个数 /* 利用getfactor函数得出因子数 , 若大于之前出现过的最大因子数,则存入d. */ int t,n,l,h,p,d; scanf("%d",&t); while(t--) { scanf("%d%d",&l,&h); d=0; for(int i=l; i<=h; i++) { n=getfactor(prime,i); if(n>d) { d=n; p=i; } } printf("Between %d and %d, %d has a maximum of %d divisors.\n",l,h,p,d); } return 0; }