1. 程式人生 > >PAT 乙級1005.繼續(3n+1)猜想(JAVA版)

PAT 乙級1005.繼續(3n+1)猜想(JAVA版)

卡拉茲(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)); } } }