【ZOJ 2562】 More Divisors

8 篇文章 0 订阅
7 篇文章 0 订阅

Description

给一个数字N,求1到N之间,哪个数的约数最多,如果有多个解,请输出值最小的那个.

Input

一行,给出数字n(1 <= n <= 10^16). 

Output

输出有多行,每行输出就是你的答案

Sample Input

10
20
100

Sample Output

6
12
60

HINT

对入输入10而言,1到10之间,6有四个约数,为约数最多的,当然8,10都有四个约数,但6的值最小,所以输出6


分析:反素数定义:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数。

性质一:一个反素数的质因子必然是从2开始连续的质数。
性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....

那题题目相当于求解小于等于N中,最大的反素数。搜索即可。这个搜索的速度是很快的。


#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
 
typedef long long LL;
int p[15]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
LL maxx,ans;
LL n;
void f(LL sum,LL num,int pos,int t)
{
    if(sum>maxx){maxx=sum;ans=num;}
    if(sum==maxx&&num<ans){ans=num;}
    LL tmp=num;
    if(pos>14)return;
    for(int i=1;i<=t;i++)
    {
        if(tmp*p[pos]>n)break;
        tmp*=p[pos];
        f(sum*(i+1),tmp,pos+1,i);
    }
}
int main() {
    while(scanf("%lld",&n)!=EOF)
    {
        maxx=0;
        ans=n;
        f(1,1,0,50);
        printf("%lld\n",ans);
    }
    return 0;
}
 
/**************************************************************
    Problem: 1258
    User: xrq
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:952 kb
****************************************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值