现在的位置: 首页 > 综合 > 正文

寒假刷题之9——Collatz序列

2014年09月05日 ⁄ 综合 ⁄ 共 2334字 ⁄ 字号 评论关闭

  The Collatz Sequence 


An algorithm given by Lothar Collatz produces sequences of integers, and is described as follows:

Step 1:
Choose an arbitrary positive integer A as the first item in the sequence.
Step 2:
If A = 1 then stop.
Step 3:
If A is even, then replace A by A / 2 and go to step 2.
Step 4:
If A is odd, then replace A by 3 * A + 1 and go to step 2.

It has been shown that this algorithm will always stop (in step 2) for initial values of A as large as 109, but some values of A encountered in the sequence may exceed the size of
an integer on many computers. In this problem we want to determine the length of the sequence that includes all values produced until either the algorithm stops (in step 2), or a value larger than some specified limit would be produced (in step 4).

Input 

The input for this problem consists of multiple test cases. For each case, the input contains a single line with
two positive integers, the first giving the initial value of 
A (for
step 1) and the second giving 
L, the limiting value
for terms in the sequence. Neither of these, 
A or L,
is larger than 2,147,483,647 (the largest value that can be stored in a 32-bit signed integer). The initial value of 
A is
always less than 
L. A line that contains two negative
integers follows the last case.

Output 

For each input case display the case number (sequentially numbered starting with 1), a colon, the initial value
for 
A, the limiting value L,
and the number of terms computed.

Sample Input 

 3 100
 34 100
 75 250
 27 2147483647
 101 304
 101 303
 -1 -1

Sample Output 

 Case 1: A = 3, limit = 100, number of terms = 8
 Case 2: A = 34, limit = 100, number of terms = 14
 Case 3: A = 75, limit = 250, number of terms = 3
 Case 4: A = 27, limit = 2147483647, number of terms = 112
 Case 5: A = 101, limit = 304, number of terms = 26
 Case 6: A = 101, limit = 303, number of terms = 1

   这题目第一感觉就是用递归或循环完成。

用递归编出如下:

#include <stdio.h>

void func(void);

long a, l;
int n = 1, i = 1;

int main()
{
	while(1){
		n = 1;
		scanf("%ld%ld", &a, &l);
		if (a < 0 && l < 0)
			break;
		func();
		printf("Case %d: A = %ld, limit = %ld, number of terms = %d\n", i ++, a, l, n);
	}
	return 0;
}

void func(void)
{
	if (a <= l && a != 1){
		n ++;
		if (a % 2 == 0){
			a = a / 2;
			func();
		}
		else{
			a = 3 * a + 1;
			func();
		}
	}
}

  好吧又wa了,不知道有中什么陷阱了。。。

  认真地检查了一遍,发现a的值被改掉了,输出时的a和输入的a值不一样。而且在25 750和101 303这两组n都多了1,郁闷,慢慢验算看看了。。。

  25是奇数25*3+1=76了,超过75所以数列只有1个,而程序算出来的却是2个,原因是没有判断运行后有没有超过限制,在函数后面加了个判断条件就ac了。

AC代码:

#include <stdio.h>

void func(void);

long a, l, temp;
int n = 1, i = 1;

int main()
{
	while(1){
		n = 1;
		if ((scanf("%ld%ld", &a, &l)) == EOF)
			break;
		if (a < 0 && l < 0)
			break;
		temp = a;
		func();
		if (a > l)
			n --;
		printf("Case %d: A = %ld, limit = %ld, number of terms = %d\n", i ++, temp, l, n);
	}
	
	return 0;
}

void func(void)
{
	if (a <= l && a > 1){
		if (a % 2 == 0){
			a = a / 2;
			func();
		}
		else{
			a = 3 * a + 1;
			func();
		}
		n ++;
	}
}

   嗯,我还是挺喜欢用递归的,很方便。



抱歉!评论已关闭.