BZOJ-1225-[HNOI2001] 求正整数

时间:2023-03-09 23:12:24
BZOJ-1225-[HNOI2001] 求正整数

Description

对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m。例如:n=4,则m=6,因为6有4个不同整数因子1,2,3,6;而且是最小的有4个因子的整数。

Input

n(1≤n≤50000)

Output

m

Sample Input

4

Sample Output

6

HINT

Source

题解

考虑这道题我们首先要知道约数个数定理

知道了这个定理后,我们不难发现可以将n分解质因数,且最多有16个质因子

这样我们可以dfs(now,nowx,s)//now表示当前取到第now个质数,nowx表示当前数,s表示对数(可以发现最后的答案是会超过long long的,所以我们存一下对数)

但是裸的dfs是会T的,需要最小值的剪枝优化

最后用高精度算一下就可以了

 #include<bits/stdc++.h>
#define N 50005
using namespace std;
const int prime[]={,,,,,,,,,,,,,,,,};
int n,cnt,num,len,k;
int a[N];
int t[];
int tmp[],b[];
double Min;
double lg[];
void mul(int x){
for (int i=;i<=len;i++) t[i]=t[i]*x;
int j=;
while (t[j]>||j<len){
t[j+]+=t[j]/;
t[j]%=;
j++;
}
len=j;
}
void dfs(int now,int nowx,double s){
if (s>=Min) return;
if (nowx==){
Min=s; k=now-;
for (int i=;i<=now-;i++) b[i]=tmp[i];
return;
}
if (now>) return;
for (int i=;(i+)*(i+)<=nowx;i++)
if (!(nowx%(i+))){
if (i){
tmp[now]=i;
dfs(now+,nowx/(i+),s+tmp[now]*lg[now]);
}
if ((i+)*(i+)!=nowx){
tmp[now]=nowx/(i+)-;
dfs(now+,i+,s+tmp[now]*lg[now]);
}
}
}
int main(){
for (int i=;i<=;i++) lg[i]=log(prime[i]);
scanf("%d",&n);
Min=1e9;
dfs(,n,);
t[]=; len=;
for (int i=;i<=k;i++){
int p=prime[i];
for (int j=;j<=b[i];j++) mul(p);
}
for (int i=len;i>=;i--)
printf("%d",t[i]);
return ;
}