标签:
题目大意是在1~2^64-1的范围内找到所有符合条件的数,条件要求这个数字是两个或两个以上不同数字的幂,例如64=8^2=4^3。
对于这一题,分析是:如果一个满足这个条件的数字一定可以转换成i^k,而且k是一个合数。同时,幂指数的上限在1~64中,这一点是通过观察筛选数字的范围
所得出的。综上,幂指数k的限定条件是(1<=k<=64,k为合数)。那么在正式筛选数字前可以通过素数筛选从而来标记出1~64中所有的合数,而对于每一种情况的幂指数就是ceil(log(2^64)/log(i))=ceil(64*(log(2)/log(i)))。
接下来需要限定的是底数的范围。我们的筛选范围的最大值也就是2^64-1,而幂指数的最小值为4,所以底数的最大值为2^16-1。则底数的范围就是1~2^16-1.
ps:2^16=1<<16;
剩下的事情就是枚举所有可能的情况,值得一提的是这里用到STL中的set可以节省很多的代码,因为set的特性就是里面的数据不重复而且是按从小到大的顺序排列的。
#include <cstdio>
#include <iostream>
#include <cmath>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>
typedef unsigned long long LL;
using namespace std;
int index[100]={ 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()
{
LL maxt=1<<16,i;
LL temp;
int maxindex,j;
ans.clear();
printf("1\n");
for(i=2;i<maxt;i++)
{
temp=i*i*i*i;
ans.insert(temp);
maxindex=ceil(64*(log(2)/log(i)))-1;//计算每数的幂指数的最大值
for(j=1;index[j]<=maxindex;j++)//筛选出每个数的幂中符合要求的数
{
if(index[j]-index[j-1]==1)
temp=temp*i;
else
temp=temp*i*i;
ans.insert(temp);
}
}
for(set<LL>::iterator iter=ans.begin();iter!=ans.end();iter++)
cout<<*iter<<endl;//这题用printf输出会出现数据丢失而且笔者未能找到有效的解决办法,若有人找到了请回复笔者怎么解决,感激不尽,此处建议用cout输出。
return 0;
}
标签:
原文地址:http://www.cnblogs.com/hbutACMER/p/4234173.html