bzoj 1225: [HNOI2001] 求正整数

来源:互联网 发布:域名不合法是怎么回事 编辑:程序博客网 时间:2024/06/07 17:54

题意:

求出具有n个不同因子的最小正整数m。

题解:

显然可以枚举因数爆搜,然而不会比大小。
于是学了对数,很好用。
这篇不错
code:

#include<cmath>#include<cfloat>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespace std;int n,ans[100005],res[21],tmp[21],pri[]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};double mn=DBL_MAX,lg[21];void print(){    ans[0]=ans[1]=1;    for(int i=1;i<=16;i++)        for(;res[i]>0;res[i]--)        {            for(int j=1;j<=ans[0];j++)                ans[j]*=pri[i];            for(int j=1;j<=ans[0];j++)                ans[j+1]+=ans[j]/10,ans[j]%=10;            if(ans[ans[0]+1]!=0)                ans[0]++;            while(ans[ans[0]]/10!=0)                ans[ans[0]+1]+=ans[ans[0]]/10,ans[ans[0]]%=10,++ans[0];        }    for(int i=ans[0];i>=1;i--) printf("%d",ans[i]);    printf("\n");}void dfs(double x,int y,int z){    if(x>mn) return;    if(y==1)    {        mn=x;        memset(res,0,sizeof(res));        for(int i=1;i<z;i++) res[i]=tmp[i];        return;    }    if(z>16) return;    for(int i=0;(i+1)*(i+1)<=y;i++)        if(y%(i+1)==0)        {            if(i!=0)            {                tmp[z]=i;                dfs(x+lg[z]*i,y/(i+1),z+1);            }            if((i+1)*(i+1)!=y)            {                tmp[z]=y/(i+1)-1;                dfs(x+lg[z]*(y/(i+1)-1),i+1,z+1);            }        }}int main(){    scanf("%d",&n);    for(int i=1;i<=16;i++)        lg[i]=log(pri[i]);    dfs(0,n,1);    print();}