Pro_100 解题思想:
根据题意,输入22,得到的数列:22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
这样我们在计算22的cycle length时,顺便得到了这一数列成员的所有cycle length
22的cycle length为16,11的cycle length为15,依次类推。
把所有计算过cycle length的数保存,以后就不必重复计算。
具体实现方法,建立长度为100000的数据数组,以及长度为500左右的临时数组。
通过他人的程序,事先可以知道的是:1-1000000的最长cycle length为525,
因而数据数组可定义为2字节的short int,临时数组500左右足矣。
例如计算22,可得到22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1的cycle length
然后再计算9,可得到9 28 14 7 22,同时写入临时数组,
当计算到22时查数组可得22的cycle length为16,
那么7的cycle length即为22的cycle length+1=17,依次逆向类推。
9 28 14的cycle length分别为20 19 18,保存到数据数组。
p.s.细节问题:
1.输入的i,j,可能存在i>j的情况,特殊处理。特别指出,先原样输出i,j,再交换。
2.在1-1000000中存在"最大飞行高度"超过2^32的数(若不清楚"最大飞行高度"请看附件介绍),但是题目保证中间过程没有超过2^32的数,所以不必定义64位整型。
源代码下载
3N+1相关资料下载
2 /* Pro_100 The 3n + 1 problem */
3 /* CPU Time 0:00.068 Memory Minimum */
4 /* Ranklist 288 Programmed By Wingy */
5 /* *********************************** */
6
7 #define MAX 1000000
8 #include < stdio.h >
9
10 int main()
11 {
12 short cir[MAX] = { 0 , 1 , 2 } ,len,j,tp,lst;
13 unsigned n,i,tm,stk[ 500 ] = { 0 } ,x,y;
14 while (scanf( " %u%u " , & x, & y) != EOF)
15 {
16 lst = 0 ;
17 printf( " %u %u " ,x,y);
18 if (x > y) tm = x,x = y,y = tm;
19 for (i = x;i <= y;i ++ )
20 {
21 if (cir[i] == 0 )
22 {
23 n = i;
24 len = 0 ;
25 while ( 1 )
26 {
27 stk[len ++ ] = n;
28 if (n & 1 ) n = 1 + n + (n << 1 );
29 else n >>= 1 ;
30 if (n < MAX && cir[n]) break ;
31 }
32 tp = len + cir[n];
33 for (j = 0 ;j < len;j ++ )
34 {
35 tm = stk[j];
36 if (tm < MAX) cir[tm] = tp;
37 tp -- ;
38 }
39 }
40 if (cir[i] > lst) lst = cir[i];
41 }
42 printf( " %d\n " ,lst);
43 }
44 return 0 ;
45 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步