题目大意
给定一个正整数 N N N,对于所有不超过 N N N的正整数,找到包含约数最多的一个数。如果有多个这样的数,那么回答最小的那个
题目解析
先给出一个定义:
若 W W W的质因数分解为:
W = p 1 W=p_1 W=p1a1 ∗ p 2 *p_2 ∗p2a2 ∗ … ∗ p m *…*p_m ∗…∗pmam ( p 1 … p m 为 素 数 , a 1 … a m ≥ 1 ) (p_1…p_m为素数,a_1…a_m≥1) (p1…pm为素数,a1…am≥1)
则 W W W有 ( a 1 + 1 ) ( a 2 + 1 ) … ( a m + 1 ) (a_1+1)(a_2+1)…(a_m+1) (a1+1)(a2+1)…(am+1)个约数
所以,可以枚举因数中包含 0 0 0个 2 2 2、 1 1 1个 2 2 2 … … … k k k个 2 2 2,直至 m ∗ 2 k m∗2^k m∗2k大于区间的上限 N N N
在这个基础上枚举
3
、
5
、
7
…
…
3、5、7……
3、5、7……的情况,算出现在已经得到的
m
m
m的约数个数,
同时与原有的记录进行比较和替换。直至所有的情况都被判定过了
接着,给出如下例子:
12 = 2 2 ∗ 3 12=2^2∗3 12=22∗3
18 = 3 2 ∗ 2 18=3^2*2 18=32∗2
12 12 12和 18 18 18的质因数分解 “ “ “模式 ” ” ”完全相同,所以它们的约数个数是相同的
但是由于 12 12 12的质因数分解中 2 2 2的指数大于 3 3 3的指数, 18 18 18的质因数分解中 3 3 3的指数大于 2 2 2的指数,所以 12 < 18 12<18 12<18
所以,可以在枚举时进行一个优化,使得枚举到的数字中 2 2 2的指数不小于 3 3 3的指数, 3 3 3的指数不小于 5 5 5的指数 … … …… ……这样我们就能够得到质因数分解 “ “ “模式 ” ” ”相同的最小数
代码
#include<bits/stdc++.h>
#define L long long
using namespace std;
L n,pi,ans,num;
int p[10005];
bool flag[1000010];
void fun()
{
for(int i=2;i<=1000000;i++)
if(!flag[i])
{
p[++pi]=i;
for(int j=2;j<=1000000/i;j++)
flag[j*i]=1;
}
}
void dfs(L x,int lev,int t,int s)
{
if(t>num||(t==num&&x<ans)) ans=x,num=t;
int j=0,l=1,q;
L i=x;
while(j<s)
{
j++,l++;
if(n/i<p[lev]) break;
q=t*l;
i*=p[lev];
if(i<=n) dfs(i,lev+1,q,j);
}
}
int main()
{
fun();
cin>>n;
dfs(1,1,1,30);
cout<<ans;
}