题目
思路
1.如何求因数的个数
2.如何确定质数的范围
我们可以发现前 15个质数之积已经大于 10^16所以我们枚举这 15 个质数就足够了。
3.如何使得所求数字尽可能小
当越小的数字的次数越大时,所得数会最小,既:
p1 < p2 < p3 < p4 < …… < pk
a1>=a2>=a3>=a4>=……>=ak
既:
第 i个质数的次数一定大于第 i+1个质数的次数
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL ans,mc,n;
const int prime[15]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
//u:当前选到了那个质数,prime的下标
//m: 当前数最大可以到多少次方
//x: 当前数已经有多大了
//cnt:当前的因子数量是多少
void dfs(int u,int m,LL x,LL cnt){
if(cnt>mc){//如果当前因子数更大,更新因字数,最小数更新为当前数
mc=cnt;
ans=x;
}else if(cnt==mc && x<ans){//如果因字数相同时,取更小的数
ans=x;
}
if(u==15) return;//当所有质数都循环完时,return;
for(int i=1;i<=m;i++){
x=x*prime[u];//求当前质数的最大次方
if(x>n) break;
dfs(u+1,i,x,cnt*(i+1));//下个因子搜索的时候,最大次数要比当前小,所以最大到i次方
}
}
int main(){
int T;
cin>>T;
while(T--){
cin>>n;
mc=0;
dfs(0,60,1,1);//由于2^60已经大于10^16,所以质数为2时,最大的次数为60次方
cout<<ans<<endl;
}
return 0;
}