【ZOJ 2562】 More Divisors

来源:互联网 发布:姚明体测数据 编辑:程序博客网 时间:2024/06/03 17:54

Description

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

Input

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

Output

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

Sample Input

1020100

Sample Output

61260

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****************************************************************/


0 0
原创粉丝点击