zoukankan      html  css  js  c++  java
  • [HNOI 2001]求正整数

    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

    题解

    这道题和[HAOI 2007]反素数ant解题思路和方法简直一毛一样...

    同样我们引入这个公式:

    对任一整数$a>1$,有$a={p_1}^{a_1}{p_2}^{a_2}…{p_n}^{a_n}$,其中$p_1<p_2<…<p_n$均为素数,而$a_1$,$a_2$…,$a_n$是正整数。

    $a$的正约数个数为:$(1+a_1)(1+a_2)…(1+a_n)$

    同理,我们也是求有$n$个因数的最小整数。

    我们最坏的情况所有质数只取$1$个,由于$15<log_{2}50000<16$

    所以只要取前$16$个质数即可,

    其余都和之前那题一样...

    搜的时候为了保存最优值,因为数据大会爆$long$ $long$我们考虑用指数幂的形式保存,带一个数组保存取质数的个数。

    同时注意每层循环枚举取质数的个数时候,因为不合法的情况很多,可以只枚举$sqrt n$次,然后用枚举的值算出对应的另外一个值。

     1 #include<set>
     2 #include<map>
     3 #include<cmath>
     4 #include<ctime>
     5 #include<queue>
     6 #include<stack>
     7 #include<cstdio>
     8 #include<string>
     9 #include<vector>
    10 #include<cstdlib>
    11 #include<cstring>
    12 #include<iostream>
    13 #include<algorithm>
    14 using namespace std;
    15 const double INF=1e100;
    16 const int pri[18]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
    17 
    18 int n;
    19 double lg[18],mm=INF;
    20 int ans[18],tmp[18];
    21 
    22 void Dfs(double e,int y,int cen)
    23 {
    24     if (e>=mm) return;
    25     if (y==1)
    26     {
    27         mm=e;
    28         memcpy(ans,tmp,sizeof(ans));
    29         return;
    30     }
    31     if (cen>16) return;
    32     for (int i=0;(i+1)*(i+1)<=y;i++) if (!(y%(i+1)))
    33     {
    34         if (i!=0)
    35         {
    36             tmp[cen]=i;
    37             Dfs(e+lg[cen]*i,y/(i+1),cen+1);
    38             tmp[cen]=0;
    39         }
    40         if ((i+1)*(i+1)!=y)
    41         {
    42             tmp[cen]=y/(i+1)-1;
    43             Dfs(e+lg[cen]*(y/(i+1)-1),i+1,cen+1);
    44             tmp[cen]=0;
    45         }
    46     }
    47 }
    48 void print()
    49 {
    50     const int MOD=1e4;
    51     int a[100000],maxn=1;
    52     a[1]=1;
    53     for (int i=1;i<=16;i++)
    54     {
    55         for (int j=1;j<=ans[i];j++)
    56         {
    57             for (int k=1;k<=maxn;k++) a[k]*=pri[i];
    58             for (int k=1;k<=maxn;k++) a[k+1]+=a[k]/MOD,a[k]%=MOD;
    59             if (a[maxn+1]) maxn++;
    60         }
    61     }
    62     printf("%d",a[maxn]);
    63     for (int i=maxn-1;i>=1;i--) printf("%04d",a[i]);
    64     printf("
    ");
    65 }
    66 
    67 int main()
    68 {
    69     scanf("%d",&n);
    70     for (int i=1;i<=16;i++) lg[i]=log(pri[i]);
    71     Dfs(0,n,1);
    72     print();
    73     return 0;
    74 }
  • 相关阅读:
    Javascript:window.close()不起作用?
    为什么全部width:100%浏览器边缘存在留白?
    hello world
    【Vue】在Vue事件中是如何使用event对象的?
    【Vue】特殊属性is
    【Vue】过滤器
    【Vue源码】Vue不能检测到对象属性的添加或删除
    【VueRouter】vue路由跳转打开新窗口
    【VueRouter】切换路由后,新页面滚动到顶部或保持原先的滚动位置——scrollBehavior
    【VueRouter】前端路由的两种模式
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7412291.html
Copyright © 2011-2022 走看看