zoukankan      html  css  js  c++  java
  • hdu 4542 打表+含k个约数最小数

    http://acm.hdu.edu.cn/showproblem.php?pid=4542

    给出一个数K和两个操作
    如果操作是0,就求出一个最小的正整数X,满足X的约数个数为K。
    如果操作是1,就求出一个最小的X,满足X的约数个数为X-K。


    对于操作0,分析见这里,搜索需要有力剪枝。对于操作1,代表1至X中不是X的约数个数为K,看似还是搜索,但是由于时限卡的丧心病狂...所以用打表完成

    d[i]先用来表示i的约数个数,然后可以模仿素数打表,对于每个数的每个倍数,其d值都自减1,这样就求出每个i对应的d[i](非约数个数)

    又由于然后对于i来讲,一定有d[i]<i,那么我们只需在求d[i]的过程中将其映射关系调换为指定非约数个数的最小的数,方法就是

    if(!d[d[i]]) d[d[i]] = i;
            d[i] = 0;
    仔细想想这两句话的意思!

    #pragma comment(linker, "/STACK:36777216")
    #pragma GCC optimize ("O2")
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define clr0(x) memset(x,0,sizeof(x))
    #define eps 1e-9
    const double pi = acos(-1.0);
    typedef long long LL;
    typedef unsigned long long ULL;
    const int modo = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int maxn = 1005,N = 50000;
    int n,pr[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
    LL ans;
    int d[N];
    
    void Init()
    {
        for(int i = 1;i < N;i++) d[i] = i;
        for(int i = 1;i < N;i++)
        {
            for(int j = i;j < N;j += i) d[j]--;
            if(!d[d[i]]) d[d[i]] = i;
            d[i] = 0;
        }
    //    for(int i = 1;i < 100;++i){
    //        cout<<i<<':'<<d[i]<<endl;
    //    }
    }
    void dfs(int dep,int cnt,LL res)
    {
        if(cnt > n)
            return;
        if(cnt == n){
            ans = min(ans,res);
            return ;
        }
        for(int i = 1;i <= 62;++i){
            if(res > ans/pr[dep] || cnt*(i+1) > n)
                break;
            res *= pr[dep];
            if(n % (cnt*(i+1)) == 0)
                dfs(dep+1,cnt*(i+1),res);
        }
    }
    int main(){
        Init();
        int _,cas = 1;RD(_);
        while(_--){
            int type;
            RD2(type,n);
            if(type)
                ans = d[n];
            else{
                ans = 1LL<<62;
                dfs(0,1,1);
            }
            printf("Case %d: ",cas++);
            if(ans == 0) puts("Illegal");
            else if(ans >= 1LL<<62) puts("INF");
            else printf("%I64d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    学习进度条
    阅读计划
    程序:随机生成30道四则运算题
    自我介绍
    构建之法阅读笔记05
    学习进度条 第十一周
    构建之法阅读笔记04
    学习进度条 第十周
    构建之法阅读笔记03
    学习进度条 第九周
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4074382.html
Copyright © 2011-2022 走看看