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