问题 E(2468): 终极大水题
时间限制: 1 Sec 内存限制: 128 MB
题目描述
对于任何正整数x,其约数的个数记作g (x)。例如
g(1)=1,g(6)=40
如果某个正整数x满足:
g(x)>g(i),0<i<x
,则称x为反质数。例如,整数1, 2, 4, 6等都是反质数。
现在给定一个数N,你能求出不超过N的最大的反质数么
输入
一个数N
输出
为不超过N的最大的反质数
样例输入
1000
样例输出
840
提示
1<=N<=2,000,000,000
我承认我第一眼觉得这道题可以先打表出来int范围内的反素数又不多(但很大啊!!)
后面突然想起了搜索,对于int,最多有32个素因数,在加上要因数尽量多,用的素数肯定没有多大,估计15个就够了,于是就可以暴力枚举每一个素因数的个数,然后算出因数个数,更新答案就行了。
dfs(now,pos,val)表示当前数的大小是now,枚举到第pos个素数,因数个数为val
于是我就T了,后面不懂,于是看了一下百度百科,瞬间觉得涨了知识。
于是乎,我加了一维状态
lim
,表示当前素数的个数限制,也就是上一个素因数的个数,然后就过了。。。。跪
下附代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
#define MAXN 20000000
#define MAXM
#define LL long long
#define INF 0x3f3f3f3f
LL N;
const LL prime[16]={1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
const int M=15;
LL ans=INF,maxnum=0;
void dfs(LL now,int pos,LL val,int lim)
{
if(val>maxnum||(val==maxnum&&now<ans))
{
ans=now;
maxnum=val;
}
if(pos>M)return;
LL tmp=now*prime[pos];
for(int i=1;i<=lim&&tmp<=N;++i,tmp*=prime[pos])
dfs(tmp,pos+1,val*(i+1),i);
}
int main()
{
scanf("%lld",&N);
dfs(1,1,1,INF);
printf("%lld\n",ans);
}