zoukankan      html  css  js  c++  java
  • UVA 11752 The Super Powers —— 数学与幂

    题目链接:https://vjudge.net/problem/UVA-11752



    题解:

    1.首先变量必须用unsig long long定义。

    2.可以分析得到,当指数为合数的时候,该值合法。

    3.由于最大值为(2^64)-1,而最小的合数为4, 所以底数最大都不超过(2^16)。且指数最大不超过64。

    那么就可以:

    枚举底数,然后计算出在最大值范围内,可以取到的最大指数。当最大指数小于4时,可以退出循环了。

    然后枚举指数,从4开始,当指数为合数时,该值合法。

    4.时间复杂度:O((2^16)* 64) < O(1e7)



    反思:
    现场做的时候,发现了:底数为素数,指数为合数的组合是合法的,且不会出现重复。

    也知道底数在1e5之内,但却没有发现指数最大都不超过64(原因没有以 2^64 为分析对象)。

    当时的想法是:在1e5之内筛选出素数和合数,然后素数与合数组合。但是没想到怎么刹车以防超过最大值。

    原来是:在组合之前,先计算出该素数下最大的指数,然后就以这个最大指数为刹车基准。

    只恨当时没想到……

    而且:不管底数是否为素数,直接枚举也不会超时。所以才导致想到了复杂的方法,这源于没有事先对复杂度作出准确的估计。




    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <string>
    #include <set>
    #define ms(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long LL;
    const int INF = 2e9;
    const LL LNF = 9e18;
    const int mod = 1e9+7;
    const int maxn = 1e5+100;
    
    int vis[100], p[100], cnt = 0;
    typedef unsigned long long ull;
    void init()
    {
        int m = (64+0.5);
        for(int i = 2; i<=m; i++)
        if(!vis[i])
        {
            p[++cnt] = i;
            for(int j = i*i; j<64; j += i)
                vis[j] = 1;
        }
    }
    
    set<ull>s;  //用set完成了排序加去重的功能
    
    int main()
    {
        init(); //标记在64以内的合数
        ull  maxx = (1LL<<64)-1;    //最大值
        for(ull i = 2;; i++)    //枚举底数
        {
            ull x = maxx;
            int t = 0;
            //尽量不要用取对数的方法求得t,因为常常出现浮点数的相关问题
            while(x>=i) //计算i的最大次幂
            {
                t++;
                x /= i;
            }
            if(t<4) break;
            x = 1;
            for(int j = 1; j<=t; j++)
            {
                x *= i;
                if(vis[j])
                    s.insert(x);
            }
        }
    
        s.insert(1);
        set<ull>::iterator it;
        for(it = s.begin(); it!=s.end(); it++)
            cout<<*it<<endl;
    }
    


  • 相关阅读:
    关于ThreadLocal的理解
    常用Linux软件安装
    Spring事务注解@Transactional失效的问题
    使用jackson转换xml格式数据进行响应
    创建简单web程序了解servlet
    JDBC
    StringBuild类
    Canlendar 日期类
    Java Date 时间类的使用
    QWeb
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538631.html
Copyright © 2011-2022 走看看