题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1060
对于一个合数 x ,分解质因数为 x = p1^a1 * p2^a2 *……*pk^ak;
从这些质因子里面选出一些乘起来,就是 x 的一个因子,假设为 y ;
对于这个合数的每一个质因子,都有 a1+1 种选择(选出0个、1个、2个……a1个该因子乘到 y 里面);
那么 x 的因子个数就是 (a1+1)*(a2+1)*……*(ak+1);
x 的因子个数尽量多就是让 ai 的成绩尽量大,由于还要 <=n ,那么 pi 就得尽量小,所以从素数表中从小到大选取素数,对于每一个素数,分配一个尽量大的ai,进行搜索。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
typedef unsigned long long LL;
const int maxn = 1e6 + 10;
LL prime[maxn];
LL ksmA[78500][64];
LL n;
LL ans;
LL cnt = 1;
void init(){
prime[0] = 1;
prime[1] = 2;
for (LL i=3; i<=maxn; i+=2){
if (!prime[i]){
prime[++prime[0]] = i;
prime[i] = 1;
LL j = i * 2;
while (j <= maxn){
prime[j] = 1;
j += i;
}
}
}
for (int i=0; i<prime[0]; i++){
ksmA[i][0] = 1;
int k = log(1e18) / log(prime[i]);
for (int j=1; j<=k; j++){
ksmA[i][j] = ksmA[i][j-1] * prime[i];
}
}
}
void dfs(int step, LL x, LL cnt_, int last){
if (cnt_ > cnt || (cnt_ == cnt && x < ans)){
cnt = cnt_;
ans = x;
}
if (x > ans) {
return;
}
for (LL i=last; i>=1; i--){
LL factor = ksmA[step][i];
if (factor == 0) continue;
if (n / x >= factor)
dfs(step+1, x*factor, cnt_*(i+1), i);
}
}
int main()
{
int t;
init();
scanf("%d", &t);
while (t > 0){
t--;
scanf("%lld", &n);
ans = n;
cnt = 0;
LL last = log(n) / log(2) + 1;
dfs(1, 1, 1, last);
cout << ans << " " << cnt << endl;
}
return 0;
}