卡拉茲(Callatz)猜想已經在1001中給出了描述。在這個題目裏,情況稍微有些複雜。
當我們驗證卡拉茲猜想的時候,爲了避免重複計算,可以記錄下遞推過程中遇到的每一個數。例如對n=3進行驗證的時候,我們需要計算3、5、8、4、2、1,則當我們對n=5、8、4、2進行驗證的時候,就可以直接判定卡拉茲猜想的真僞,而不需要重複計算,因爲這4個數已經在驗證3的時候遇到過了,我們稱5、8、4、2是被3“覆蓋”的數。我們稱一個數列中的某個數n爲“關鍵數”,如果n不能被數列中的其他數字所覆蓋。
現在給定一系列待驗證的數字,我們只需要驗證其中的幾個關鍵數,就可以不必再重複驗證餘下的數字。你的任務就是找出這些關鍵數字,並按從大到小的順序輸出它們。
輸入格式:每個測試輸入包含1個測試用例,第1行給出一個正整數K(<100),第2行給出K個互不相同的待驗證的正整數n(1
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = Integer.parseInt(scan.nextLine());
//等號左邊右邊的泛型參數有的編譯器都要填寫,比如pat的就要寫
HashMap<String, Integer> map = new HashMap<String, Integer>();
String[] line = scan.nextLine().split(" ");
for (int i = 0; i < num; i++) {
int n = Integer.parseInt(line[i]);
findStrange(n, map);
}
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < line.length; i++) {
if(!map.containsKey(line[i])){
list.add(new Integer(Integer.parseInt(line[i])));
}
}
for (int i = 0,size = list.size(); i < size; i++) {
for (int j = i; j < size; j++) {
if (list.get(i) < list.get(j)) {
int t = list.get(i);
list.set(i, list.get(j));
list.set(j, t);
}
}
}
for (int i = 0; i < list.size(); i++) {
if (i == list.size() -1) {
System.out.println(list.get(i));
}else{
System.out.print(list.get(i) + " ");
}
}
}
/*
* 找出被覆蓋的樹都加到map中,重複的map不會添加
*/
private static void findStrange(int num, HashMap<String,Integer> map) {
while (num > 0 && num != 1) {
if (num % 2 == 1) {
num = (3 * num + 1)/2;
}else{
num = num / 2 ;
}
map.put(String.valueOf(num), new Integer(num));
}
}
}