【搜索】【CQBZOJ 2468】终极大水题(反素数)

问题 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)nowposval

于是我就T了,后面不懂,于是看了一下百度百科,瞬间觉得涨了知识。
来自Baidu百科

于是乎,我加了一维状态 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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值