看lrj的白书刚好看到类似的题,顺手做一下
Description
在计算机科学上,有很多类问题是无法解决的,我们称之为不可解决问题。然而,在很多情况我们并不知道哪一类问题可以解决,那一类问题不可解决。现在我们就有这样一个问题,问题如下:
1. 输入一个正整数n;
2. 把n显示出来;
3. 如果n=1则结束;
4. 如果n是奇数则n变为3n+1 ,否则n变为n/2;
5. 转入第2步。
例如对于输入的正整数22,应该有如下数列被显示出来:
22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
我们推测:对于任意一个正整数,经过以上算法最终会推到1。尽管这个算法很简单,但我们仍然无法确定我们的推断是否正确。不过好在我们有计算机,我们验证了对于小于1,000,000的正整数都满足以上推断。
对于给定的正整数n,我们把显示出来的数的个数定义为n的链长,例如22的链长为16。
你的任务是编写一个程序,对于任意一对正整数i和j,给出i、j之间的最长链长,当然这个最长链长是由i、j之间的其中一个正整数产生的。我们这里的i、j之间即包括i也包括j。
Input
输入文件只有一行,即为正整数i和j,i和j之间以一个空格隔开。0 < i ≤ j < 10,000。
Output
文件只能有一行,即为i、j之间的最长链长。
刚开始理解错题意,还以为是从j推到i和从i推到j的数链取最大……各种死循环,然后才发现其实是在i到j之间找推到1需要的操作最多的那个数
如果看懂了题其实很水很水……
View Code
1 #include<stdio.h> 2 int length( int n ); 3 4 int main() 5 { 6 int i, j; 7 int k; 8 int max = 0; 9 10 scanf("%d %d", &i, &j ); 11 12 for ( k = i; k <= j; k++ ) 13 { 14 if ( length(k) >= max ) 15 { 16 max = length(k); /* 更新最大值 */ 17 } 18 } 19 20 printf( "%d\n", max ); 21 22 return 0; 23 } 24 25 int length( int n ) 26 { 27 int length = 1; 28 29 while ( n != 1 ) 30 { 31 if ( n % 2 == 1 ) 32 { 33 n = n * 3 + 1; 34 } 35 else 36 { 37 n /= 2; 38 } 39 40 length++; 41 } 42 43 return length; 44 }