UVa11752

来源:互联网 发布:c语言 long类型 编辑:程序博客网 时间:2024/05/14 06:31

简介:
找出2^64以内同时是至少两个整数的幂的数

分析:
在我们不知道怎么做的时候,我们要怎么办呢
打表
不不不,这道题不能这样

假设我们需要判断X是否可行
我们把数字质因数分解一下
可以发现,如果ta的所有因子的个数互相成倍数关系并且都可以被两个不同的数整除,那么X一定是super power

网上给出这样一句话:

只有幂是合数才可以进行拆分

就是把X变成底数最小的指数式,指数一定要是合数,
这样我们可以通过拆分指数得到不同的底数

因为数字最大就到2^64-1,所以指数是不会超过64的,又因为指数一定是合数,所以我们可以先预处理出64以内的合数

又因为64以内的合数最小是4,所以底数最大不超过2^16
这样直接枚举底数和指数,用set判重

tip

我一开始认为,如果从2依次枚举底数,肯定会有重复的,
所以只枚举素数就可以了,既可以避免重复,又可以不用自己不熟悉的set
但是这样写出来,得到的数要比正确答案少得多
我也不清楚为什么

实在没办法,只能改成set判重
但是写出来以后也跑不出正确答案,原来是在乘的时候int和ll混用了

于是突发奇想,把之前枚举素数的程序改了一下(全改成ll)
但是还是跑不出来正确答案
看来就是错误算法

unsigned long long输出的时候用%llu

//这里写代码片#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<set>using namespace std;typedef unsigned long long ll;const ll N=1<<16;int hes[50]={4,6,8,9,10,12,14,15,16,18,20,21,22,24,25,26,27,28,30,32,33,34,35,36,38,39,40,42,44,45,46,48,49,50,51,52,54,55,56,57,58,60,62,63,64};set<ll> ans;int main(){    for (ll i=2;i<N;i++)    {        int maxx=ceil(64*log(2)/log(i))-1;                //这样不会出错         ll now=i*i*i*i;        ans.insert(now);        for (int j=1;hes[j]<=maxx;j++)        {            for (int k=hes[j-1]+1;k<=hes[j];k++)                now*=i;            ans.insert(now);        }    }    printf("1\n");    for (set<ll>::iterator i=ans.begin();i!=ans.end();i++)        printf("%llu\n",*i);    return 0;}
原创粉丝点击