1. 程式人生 > >2019年藍橋杯練習1-序列生成演算法

2019年藍橋杯練習1-序列生成演算法

 2019年藍橋杯練習1-序列生成演算法

3n+1問題

PC/UVa IDs: 110101/100

Popularity: A

Success rate: low Level: 1

測試地址:

https://vjudge.net/problem/UVA-100

[問題描述]

考慮如下的序列生成演算法:從整數 n 開始,如果 n 是偶數,把它除以 2;如果 n 是奇數,把它乘 3 加1。用新得到的值重複上述步驟,直到 n = 1 時停止。例如,n = 22 時該演算法生成的序列是:

22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1

人們猜想(沒有得到證明)對於任意整數 n,該演算法總能終止於 n = 1。這個猜想對於至少 1 000 000內的整數都是正確的。

對於給定的 n,該序列的元素(包括 1)個數被稱為 n 的迴圈節長度。在上述例子中,22 的迴圈節長度為 16。輸入兩個數 i 和 j,你的任務是計算 i 到 j(包含 i 和 j)之間的整數中,迴圈節長度的最大值。

[輸入]

輸入每行包含兩個整數 i 和 j。所有整數大於 0,小於 1 000 000。

[輸出]

對於每對整數 i 和 j,按原來的順序輸出 i 和 j,然後輸出二者之間的整數中的最大迴圈節長度。這三個整數應該用單個空格隔開,且在同一行輸出。對於讀入的每一組資料,在輸出中應位於單獨的一行。

[樣例輸入]

1 10

100 200

201 210

900 1000

[樣例輸出]

1 10 20

100 200 125

201 210 89

900 1000 174

//每週一練/1
#include<stdio.h>
int fun(long n) {  //避免出現 3*n+1 的值溢位 
	int count=0; //記錄迴圈節長度 
	while(n!=1) {
		if(n%2!=0) {
  		    n=3*n+1;  //n為奇數 
        } else {
        	n=n/2;   //n為偶數 
		}
		count++;
	}
	return count+1;  //算上n=1 
}
int main()
{
 	int i,j;
	while(scanf("%d %d",&i,&j)==2) {
		//坑!當輸入的i>j時
		int i1,j1;
		i1=i;
		j1=j;
		if(i>j) {
			i1=j;
			j1=i; 
		} 
		int max=0;  //記錄最大迴圈節長度 
		for(int a=i1;a<=j1;a++) {
			if(fun(a)>max) max=fun(a); 
		} 
		printf("%d %d %d\n",i,j,max);
	}	
	return 0; 
} 

/*
總結:
1.當計算 (n * 3 + 1) 時,中間計算過程會超過 32位整數的表示範圍而得到錯誤答案。
2.題目沒有明確說輸入時小數在前,大數在後,所以輸入時可能較大的數在前面,需要調整順序 
*/