ACM UVa problem 3n+1

来源:互联网 发布:淘宝淘营销入口在哪里 编辑:程序博客网 时间:2024/05/19 09:16
一背景
    写这篇文章的目的是为了记录算法研究过程的中的一点一滴,让自己每天可以沐浴在算法所带来的快乐中,以后我会坚持地往上面发自己曾经做过的ACM的题目,然后做出详细的分析,总结自己的错误和失误,如果有什么不足之处,望请大家指正。

二问题
    由于是英文的,这里我没有翻译成汉语的。
   


 The 3n + 1 problem 

Background

Problems in Computer Science are often classified as belonging to a certain class of problems (e.g., NP, Unsolvable, Recursive). In this problem you will be analyzing a property of an algorithm whose classification is not known for all possible inputs.

The Problem

Consider the following algorithm:

 
1. input n


2. print n


3. if n = 1 then STOP


4. if n is odd then tex2html_wrap_inline44


5. else tex2html_wrap_inline46


6. GOTO 2


Given the input 22, the following sequence of numbers will be printed 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

It is conjectured that the algorithm above will terminate (when a 1 is printed) for any integral input value. Despite the simplicity of the algorithm, it is unknown whether this conjecture is true. It has been verified, however, for all integers n such that 0 < n < 1,000,000 (and, in fact, for many more numbers than this.)

Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.

For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j.

The Input

The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 1,000,000 and greater than 0.

You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.

You can assume that no operation overflows a 32-bit integer.

The Output

For each pair of input integers i and j you should output i, j, and the maximum cycle length for integers between and including i and j. These three numbers should be separated by at least one space with all three numbers on one line and with one line of output for each line of input. The integers i and j must appear in the output in the same order in which they appeared in the input and should be followed by the maximum cycle length (on the same line).

Sample Input

1 10
100 200
201 210
900 1000

Sample Output

1 10 20
100 200 125
201 210 89
900 1000 174

三 AC代码

/*************************************CODE REGION************************************************/
/*ACM problem: 3n+1
*作者:lynnwong
*日期:2008-5-14
*email: shuai.wang.zju@gmail.com
*/

#include<iostream>
using namespace std;

/*获取每一个整数的3n+1 cycle的长度*/
int GetLength(unsigned long n)
{
int count;
for( count = 1; n != 1; count ++)
{
if ( n % 2 == 0)
{
n /= 2;
}
else
{
n = 3 *n + 1;
}
}
return count;
}

int main()
{
unsigned long start,end;//start和end为区间的开始和结束的数字
int curLength,maxLength;//curLength为当前获取的cycle长度, maxLength为比较后的最大长度


while(cin >> start >> end)
{
int temp = 0 ;
bool isSwap = false;
if(start > end)
{
temp = start;
start = end;
end = temp;
isSwap = true;
}

//if( start <= 0 || end >= 1000000) return 0 ;
maxLength = 1;//最大长度初始化为0
for ( unsigned long n = start; n <= end; n++)
{
if (n ==1) continue;
curLength = GetLength(n);
if( curLength > maxLength)
{
maxLength = curLength;
}
}
if(isSwap)
{
temp = start;
start = end;
end = temp;
}
cout << start << " " << end << " " << maxLength << endl;
}

//system("PAUSE");//如果在devcpp编译器下编译,调试过程中取消该注释
}
/*************************************CODE REGION************************************************/
四.分析和总结

1.什么时候使用递归
在刚开始的时候,我在写11行的GetLength()函数的时候,函数体内部使用的是递归的方法来实现的。但是,
后来在调试的过程中,发现递归很容易出错,最后经过研究发现,本问题仅仅为了获取单个自然数的Cycle的数值
并没有其他的操作,就放弃递归的方法,而采用一个for循环,每次循环的过程中递增count,直到n为1的时候停
止。杀鸡焉用牛刀。
2.注意int 和 long 的位数
刚开是程序可以通过sample的例子,但是不能AC,经调试发现程序执行到113382的时候停止。在仔细看问题说
明,原来,N的大小的上限为1,000,000。这样是很明显不可以满足的。在c++的编译环境下,就算unsigned int
也只有16位,最大的值只能到65535.故要注意采用,unsinged long 的类型,展32位bit.在一些现代的编译语言
这种情况可能要失效。如下:
c++ short 16位 int 16位 long 32位
c# short 16位 int 32位 long 64位
因此在和数值有关的问题的时候,一定要注意数据类型所能表示的最大整数,和题目中问题所涉及的最大范围。
3.Swap
本问题提交了10次才被接受,在前九次中都是WA,一直找不到原因,最后试下把输入的范围i j先比较大小,保证
为从小到大的排序,因为问题中的给的测试数据并没有明确给明是从小到大了,这样浪费的很多的时间。下次这方面
一定要注意。

五.Judge地址

http://icpcres.ecs.baylor.edu/onlinejudge/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=36

如果有什么错误之处可以和我联系,
email: shuai.wang.zju@gmail.com