天天看點

ACM訓練題 3n+1問題

問題描述]*考慮如下的序列生成算法:

從整數 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

一開始總是沒有明白這個i——j到底是幹什麼的,後來讀了兩片之後才明白。原來是讓我比較i到j之間循環節長度的最大值的。這個程式呢,是用java寫的,用c語言稍微改改就可以了。由于懶性讓我不想改。

package com.imooc.bean;

import java.util.Scanner;

public class ThreeN {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int[] as = new int[8];

for (int i = 0; i < as.length; i++) {

as[i] = sc.nextInt();

}

System.out.println(“輸出結果:”);

for (int j = 0; j < as.length; j = j + 2) {

int max = 1;

for (int i = as[j]; i <= as[j + 1]; i++) {

int c = test(i);

if (max <= c) {

max = c;

}

}

System.out.println(as[j] + " " + as[j + 1] + " " + max);

}

}

public static int test(int a) {
	int b = 1;
	while (true) {
		if (a % 2 == 0) {
			a = a / 2;
		} else if (a % 2 == 1) {
			a = a * 3 + 1;
		}
		b++;
		if (a == 1) {
			return b;
		}

	}
}
           

}