以下是csdn的网友提出的几种方法,仅供参考。
(1)
3^n = (2+1)^n = C(n,0)*2^0*1^n+C(n,1)*2^1*1^(n-1)+....+C(n,n)*2^n*1^0
=C(n,0)*2^0+C(n,1)*2^1+C(n,2)*2^2+....+C(n,n)*2^n
=1+C(n-1)*2^1+C(n,2)*2^2+...+C(n,n)*2*n
有网友说: 判断 3^n-1 这个数是不是2的幂,然后利用本版以前讨论那个(n&(n-1))来
判断n是不是2的幂。这个不是充分必要条件,但是思想确实不错。
(2)
第一题:
测试函数:
template<class Integer>
bool isPow3(const Integer & n);
测试代码:
int main()
{
using namespace std;
typedef long __Type;
long start = clock();
for(__Type i = 0;i <= 100000000;++i)
if(isPow3(i))
cout<<i<<" ";
start = clock() - start;
cout<<endl<<"Time: "<<start<<endl;
}
原理1:用乘法,判断等于
版本1:
template<class Integer>
bool isPow3(const Integer & n){
Integer p = 1;
while(p < n)
p *= 3;
return p == n;
}
结果:
1 3 9 27 81 243 729 2187 6561 19683 59049 177147 531441 1594323 4782969 1434
8907 43046721
Time: 2531
版本2:
template<class Integer>
bool isPow3(const Integer & n){
Integer p = 1;
while(p < n)
p *= 9;
return p == n || p == n * 3;
}
结果:
1 3 9 27 81 243 729 2187 6561 19683 59049 177147 531441 1594323 4782969 1434
8907 43046721
Time: 1265
版本3:
template<class Integer>
bool isPow3(const Integer & n){
Integer p = 1;
while(p < n)
p *= 27;
return p == n || p == n * 3 || p == n * 9;
}
结果:
1 3 9 27 81 243 729 2187 6561 19683 59049 177147 531441 1594323 4782969 1434
8907 43046721
Time: 1328
原理2:预先保存好所有结果,折半查找
版本4:
template<class Integer>
bool isPow3(const Integer & n){
static const Integer POW_3[18] =
{1,3,9,27,81,243,729,2187,6561,19683,59049,177147,531441,1594323,478
2969,14348907,43046721,129140163};
static const std::set<Integer> RESULT(POW_3,POW_3 + 18);
return !(RESULT.find(n) == RESULT.end());
}
结果:
1 3 9 27 81 243 729 2187 6561 19683 59049 177147 531441 1594323 4782969 1434
8907 43046721
Time: 3875
结论是版本2最快,预置结果的版本4不能和版本2,3相比,毕竟查找也要时间。
坚决不跟用TC的人打交道!