数字实力
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 406 测试通过 : 77
总提交 : 406 测试通过 : 77
题意:给出n,求出1到n中因子最多的数极其因子的个数。
分析:数据很大,暴力肯定超时。首先得知道求取一个数因子个数的方法,在此给出结论,若一个数存在质因子a1、a2…ak,且a1^b1*a2*b2…ak^bk=n,则其因子数为(b1+1)*(b2+1)*…*(bk+1),具体解释可参见http://blog.sina.com.cn/s/blog_818d3d9301017436.html ,叙述非常易懂。所以该题需要转移到求取质因子,如果直接遍历判断质数的话又会超时,在此需要筛选出质数数组,在质数数组的情况下进行遍历判断可大大节省时间。所以该题需要用到筛素数的算法,版本非常多,在此不赘述。见AC代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxn=500005;
bool is[maxn];
int prm[maxn];
int getprm(int n)//筛素数
{
int i, j, k = 0;
int s, e = (int)(sqrt(0.0 + n) + 1);
memset(is, 1, sizeof(is));
prm[k++] = 2;
is[0] = is[1] = 0;
for (i = 4; i < n; i += 2) is[i] = 0;
for (i = 3; i < e; i += 2)
if (is[i])
{
prm[k++] = i;
for (s = i * 2, j = i * i; j < n; j += s)
is[j] = 0;
}
for ( ; i < n; i += 2)
if (is[i])
prm[k++] = i;
return k;
}
int count(int n) //求一个数的因子个数
{
int cnt=0,res=1;
for(int i=0; prm[i]*prm[i]<=n; i++)
if(n%prm[i]==0)
{
cnt=0;//注意cnt每次需要重置为0
while(n%prm[i]==0)
{
cnt++;
n/=prm[i];
}
res*=(cnt+1);
}
if(n!=1)//如果最后剩下非1质因子 如7之类的
res*=2;
return res;
}
int main()
{
int n;
getprm(maxn);
while(~scanf("%d",&n))
{
int res=0,num;
for(int i=1; i<=n; i++)
if(count(i)>res)
{
res=count(i);
num=i;
}
printf("%d %d\n",num,res);
}
}
特记下,以备后日回顾。