[luogu p1221][codevs 1032]最多因子数

 

 

 

题目描述

数学家们喜欢各种类型的有奇怪特性的数。例如,他们认为945是一个有趣的数,因为它是第一个所有约数之和大于本身的奇数。

为了帮助他们寻找有趣的数,你将写一个程序扫描一定范围内的数,并确定在此范围内约数个数最多的那个数。不幸的是,这个数和给定的范围的都比较大,用简单的方法寻找可能需要较多的运行时间。所以请确定你的算法能在几秒内完成最大范围内的扫描。

输入输出格式

输入格式:

只有一行,给出扫描的范围,由下界L和上界U确定。满足2≤L≤U≤1000000000。

输出格式:

对于给定的范围,输出该范围内约数个数D最多的数P。若有多个,则输出最小的那个。请输出“Between L and U,P has a maximum of D divisors.”,其中L,U,P和D的含义同前面所述。

输入输出样例        别点复制,没用的:)

输入样例#1: 复制

1000 2000

输出样例#1: 复制

Between 1000 and 2000, 1680 has a maximum of 40 divisors.

传送门

这题的思路嘛。。。。

其实就是爆搜。

首先我们要知道,一个数X可以被分解为X=2^m1∗3^m2∗5^m3∗...∗n^mk

相信聪明的大家都能理解(注:n为质数)

当分解完后,X的个数为(m1+1)∗(m2+1)∗(m3+1)∗...∗(mk+1)

根据乘法原理,选1个,2个……m1个,为啥是m1+1?还可以不选haha

我们只需把质数预处理出来,然后暴力填m1,m2,m3,……,mk即可

加上一点小剪枝

代码:(卡常大法好)

#include
#define ll long long
using namespace std;
const int N = 10005;
const int INF = 1000000007;
ll _[N],prime[N],size,ansp=INF,ansd,anss[N],l,r;
//p 素数 2 3 5 7 (第几个质因子)
//all已经搜索到的k的因子的乘积
//last上一个的p的指数 
inline void dfs(int p,ll all,ll last){
    if(l<=all&&all<=r){//满足要求
        int o=1;
        for(register int i=1;iansd||(o==ansd&&allansp) return;//最优性剪枝
    ll lin[100]={0};
    lin[0]=1;
    for(register int i=1;i<=last;i++) lin[i]=lin[i-1]*prime[p];//预处理
    for(register int i=last;i>=1;i--){//从后往前,更高效
        anss[p]=i;	
        dfs(p+1,all*lin[i],i);
    }
}
void bao_li_chu_qi_ji(){//只可会意,不可言传
    for(int i=l;i<=r;i++){
        int ret=0;
        for(int j=1;j*j<=i;j++){
            if(i%j==0) ret+=2;
            if(j*j==i) ret--;
        }
        if(ret>ansd){
            ansp=i;
            ansd=ret;
        }
    }
}
int main(){
    for(register int i=2;i<=sqrt(N);i++){
        for(register int j=2;j*i

跑得还挺快的。。

你可能感兴趣的:(搜索)