POJ 1207 The 3n + 1 problem

这题是水题,太水了...

刚开始觉得题目给的范围还挺大的,于是想到了记忆化搜索,记录中间结果,以后查询的时候就不用再搜索。结果由于某些原因,想得太简单,没有考虑到这个数将会上升得非常快,超出了MaxN(1,000,000)的范围,造成下标越界。后来又想到这个数只有当它为2的n次幂的时候才会收敛,于是该了一下,438ms过了。

后来发现网上居然还有暴力枚举的方法,还0ms就AC了,令我很不爽。在本机上试了一下,这种方法在查询900,000~1,000,000的时候就会挂掉,跑了很久不出结果。于是,将该题鉴定为水题。

其实今天是想做做POJ 1144 Network,但是还有些问题没解决,并且发现书上的内容貌似是错的,于是就没继续做,打算放一两天。但是每天一题还是要坚持,于是用比较好的方法过了一道水题。做水题还是要用心~~安心睡觉吧。

ContractedBlock.gif ExpandedBlockStart.gif Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 
 5 const int MaxN = 1000010;
 6 short len[MaxN];
 7 
 8 int search(long long i) {
 9     if(i < MaxN && len[i])
10         return len[i];
11     if((int)ceil(log(1.0*i)) == (int)floor(log(1.0*i)))
12         return (int)log(1.0*i) - 1;
13     int t;
14     if(i&1)
15         t = search(3*i+1+ 1;
16     else
17         t = search(i/2+ 1;
18     if(i < MaxN) len[i] = t;
19     return t;
20 }
21 
22 void G() {
23     len[1= 1;
24     for(int t = 1, m = 1; t < MaxN; ++m, t *= 2) {
25         len[t] = m;
26     }
27     for(int i = 1; i < MaxN; ++i) {
28         if(!len[i])
29             len[i] = search(i);
30     }
31 }
32 
33 int main() {
34     int a, b, c, d;
35     while(scanf("%d%d"&a, &b) == 2) {
36         G();
37         c = a; d = b;
38         if(a > b) {a ^= b; b ^= a; a ^= b;}
39         int Max = 0;
40         for(int i = a; i <= b; ++i) {
41             if(len[i] > Max)
42                 Max = len[i];
43         }
44         printf("%d %d %d\n", c, d, Max);
45     }
46     return 0;
47 }
48 

转载于:https://www.cnblogs.com/destinydesigner/archive/2009/09/28/1576024.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值