UVA - 11752 The Super Powers 【超級冪+數論+暴力列舉】
阿新 • • 發佈:2018-11-19
題目描述:稱一個可以由至少兩個不同正整數的冪的形式表示的數為超級冪。輸出1~2^64-1之間的所有超級冪。
解題思路:由數論基本定理可知,任何一個數都可以分解為素數的乘積。如果一個數可以表示為n^k且這個數為超級冪那麼指數k必須為合數(自然數中除了能被1和本身整除外,還能被其他的數整除的數)。設一個數由兩部分組成,底數和指數:
底數最小為2,那麼指數最大為64;
指數最小為4;那麼底數最大為2^16;
暴力列舉,利用容器set去重且從小到大自動排序
AC程式碼:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define inf 0x3f3f3f typedef long long ll; typedef unsigned long long ULL; const int mod=1e9+7; const ULL maxn=(1<<64)-1; bool isprime[66]; void getprime()//找出將小於等於64的所有合數,並賦值為false { memset(isprime,true,sizeof(isprime)); for(int i=2;i<=64;i++) for(int j=2;j*j<=i;j++) if(i%j==0) isprime[i]=false; } set <ULL> s; int main() { getprime(); s.insert(1); for(int i=2;i<=(1<<16);i++)//列舉底數 { ULL ans=1; for(int j=1;j<=64;j++)//列舉指數 { ans*=i; if(!isprime[j]) s.insert(ans); if(ans>maxn/i)//防止ans大於邊界 break; } } set <ULL>::iterator a; for(a=s.begin();a!=s.end();a++)//輸出所有超級冪 cout<<*a<<endl; return 0; }