ProjectEuler Problem 29: Distinct powers
Mar 24, 2014
Problem 29: Distinct powers #
nsider all integer combinations of a^b for 2 ≤ a ≤ 5 and 2 ≤ b ≤ 5:
2^2=4, 2^3=8, 2^4=16, 2^5=32
3^2>=9, 3^3=27, 3^4=81, 3^5=243
4^2=16, 4^3=64, 4^4=256, 4^5=1024
5^2=25, 5^3=125, 5^4=625, 5^5=3125
If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms:
4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125
How many distinct terms are in the sequence generated by a^b for 2 ≤ a ≤ 100 and 2 ≤ b ≤ 100?
分析 #
不同的幂。a^b,其中 2 ≤ a ≤ 100, 2 ≤ b ≤ 100,所有的不相等的结果的个数。
方法 直接遍历统计 #
最大为100^100 为201位,这些都可以放到一个double类型里面(double的位数大约在300位)。使用set来存储,就可以去除重复。
C++标准库中没有大数处理函数,做OJ真是一大痛啊。不过话说回来,如果都象Python一样,那么OJ也就失去了很多意义了。这也是我这个系列一直坚持,每题都用C\C++和Python两种语言解决的原因。
C++ #
使用 double 类型存储幂, 使用 STL set 确保不重复
#include <iostream>
#include <set>
#include <cmath>
int main()
{
std::set<double> answer;
for (double a = 2; a <= 100; a++)
for (double b = 2; b <= 100; b++)
answer.insert(pow(a,b));
std::cout << answer.size();
return 0;
}
感谢Darryl (Project Euler 论坛 第一页)。 没想到double类型这么能装,不过总觉得这么做还是有点点侥幸,如果不是2~100,改成2~1000呢?方法就不适用了。
Golang #
因为float64的精度问题,golang中不能直接使用float64来解决本题的大数问题,需要使用大数包
package main
import (
"fmt"
"math/big"
)
func pow(a, b int) *big.Int {
ret := big.NewInt(int64(a))
bigA := big.NewInt(int64(a))
for i:=2; i <= b; i++ {
ret.Mul(ret, bigA)
}
return ret
}
func main() {
answer := make(map[string]struct{}) // value 使用 struct{} 可以不占内存
for a := 2; a <= 100; a++ {
for b := 2; b <= 100; b++ {
n := pow(a,b)
answer[n.String()] = struct{}{}
}
}
fmt.Println(len(answer))
}
Python #
一行代码,使用set存储,自动去重,使用len()统计个数
print (len(set([a**b for a in range(2,101) for b in range(2,101)])))
答案 #
9183