UVa——100 - The 3n + 1 problem(打表)

解题思路:这道题题意很明确,就是从整数 n 开始,如果 n 是偶数,把它除以 2;如果 n 是奇数,把它乘 3 加 1。用新得到的值重复上述步骤,直到 n=1 时停止。计算 i 到 j 之间的整数中,循环节长度的最大值。由于n 是不小于1000 000的整数,所以用递归虽然很方便,但是容易超时,后来改为递推仍然超时。其实想想有的数会重复计算,因此可以用数组保存下来,也就是我们通常所说的打表方法。

注意:输出的整数 m 与 n ,不一定是 m<n,所以要做交换,使其满足条件。由于要求输出这两个整数,所以刚开始要保存下来。

另外请注意编译环境问题,UVa中不支持__int 64 类型,支持 long long 型,而在C++6.0中则恰恰相反。

View Code
 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 #define MAX 1000005
 5 int an[MAX];
 6 int main()
 7 {
 8     int i,m,n,t,a,b;
 9     an[1]=1;
10     an[2]=2;
11     for(i=3;i<MAX;i++)
12     {
13         long long k;
14         k=i;
15         int sum=0;
16         while(1)
17         {
18             if(k%2==1)
19             {
20                 k=3*k+1;
21                 sum++;
22             }
23             else{
24                 sum++;
25                 k=k/2;
26             }
27             if(k<i) //判断是否已经计算出
28             {
29                 an[i]=sum+an[k];
30                 break;
31             }
32         }
33     }
34     while(scanf("%d%d",&m,&n)!=EOF)
35     {
36         int max=0;
37         a=m;b=n;
38         if(m>n) { t=m;m=n;n=t; }
39         for(i=m;i<=n;i++)
40             if(max<an[i]) max=an[i];
41             printf("%d %d %d\n",a,b,max);
42     }
43     return 0;
44 }

 

posted @ 2012-02-24 17:23  笑巧  阅读(399)  评论(0编辑  收藏  举报