[Project Euler] Problem 14

The following iterative sequence is defined for the set of positive integers:

n →n/2 (n is even)
n → 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

Which starting number, under one million, produces the longest chain?

NOTE: Once the chain starts the terms are allowed to go above one million.

 

寻找小于1,000,000的按Collatz Problem规律能形成最长序列的数

有两种思路:

首先,直接暴力搜索,按问题的规模来说,应该不是特别慢

第二种,动态规划,先把小的数的解的结果保存起来,若大数转化为小数,直接利用小数的解求得大数的解

 

我们来对比一下两种求法的效率

 
   
#include < iostream >
#include
< ctime >
#include
< cstdlib >
using namespace std;

const int NUM = 100000 ;
int flag[NUM + 1 ] = { 0 };

int search( long long i, int limit){
int tmp = i;
int len = 0 ;
while (i != 1 ){
if (i % 2 == 0 ){
len
++ ;
i
= i / 2 ;
if (i < limit && i < tmp){
len
+= flag[i];
if (tmp < limit){
flag[tmp]
= len;
}
return len;
}
}
else {
i
= 3 * i + 1 ;
len
++ ;
}
}
return len;
}


int search2( long long i){
int len = 1 ;
while (i != 1 ){
if (i % 2 == 0 ){
i
/= 2 ;
}
else {
i
= 3 * i + 1 ;
}
len
++ ;
}
return len;
}

int main(){
int max = 0 , limit = NUM;
int which = 0 ;
int tmp;
long long i = 1 ;
clock_t start,finish;

for ( int j = 0 ;j < 3 ;j ++ ){
i
= 1 ;
max
= 0 ;
start
= clock();
while (i < 1000000 ){
tmp
= search(i,limit) + 1 ;
if (max < tmp){
max
= tmp;
which
= i;
}
i
++ ;
}
finish
= clock();
cout
<< max << ' \t ' << which << ' \t ' ;
cout
<< " Time : " << finish - start << ' \t ' ;
cout
<< " limit : " << limit << endl;
limit
/= 10 ;
}


i
= 1 ;
max
= 0 ;
start
= clock();
while (i < 1000000 ){
tmp
= search2(i);
if (max < tmp){
max
= tmp;
which
= i;
}
i
++ ;
}
finish
= clock();
cout
<< max << ' \t ' << which << ' \t ' ;
cout
<< " Time : " << finish - start << endl;

return 0 ;
}

 

2011022413452779.png

 

我们可以看到,保存的小数的解越多,整个计算的过程也就越快

而直接暴力搜索总是最慢的

 

还有一点要注意的是,一个在1,000,000以下的数,按规律计算,计算的过程中,可能得到非常大的数,

会超过int的范围,所以要声明为long long型。我在网上看到有人声明为unsigned long型,虽然结果是对的,

但其实计算已经出现了错误,实际上是直接把超出int的部分截断了。

 

 

转载于:https://www.cnblogs.com/xianglan/archive/2011/02/24/1963713.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值