1. 程式人生 > 其它 >PTA-乙級1005 繼續(3n+1)猜想 (25 分)-JAVA

PTA-乙級1005 繼續(3n+1)猜想 (25 分)-JAVA

為了方便看題,這裡給出卡拉茲猜想:

卡拉茲(Callatz)猜想:

對任何一個正整數,如果它是偶數,那麼把它砍掉一半;如果它是奇數,那麼把砍掉一半。這樣一直反覆砍下去,最後一定在某一步得到。卡拉茲在 1950 年的世界數學家大會上公佈了這個猜想,傳說當時耶魯大學師生齊動員,拼命想證明這個貌似很傻很天真的命題,結果鬧得學生們無心學業,一心只證,以至於有人說這是一個陰謀,卡拉茲是在蓄意延緩美國數學界教學與科研的進展……

我們今天的題目不是證明卡拉茲猜想,而是對給定的任一不超過 1000 的正整數,簡單地數一下,需要多少步(砍幾下)才能得到

題意:
我們在第一行輸入要判斷數字的數量,第二行輸入待驗證卡拉茲猜想的正整數,關鍵是我們如何找出這些“關鍵數”,關鍵數就是說在我們輸入的數中,如果在求一個數的卡拉茲猜想過程中出現過了,那我們就把這些數稱作非“關鍵數”,然後剩下的數就是關鍵數。

思路:

這道題一開始我是想要通過用變數記錄的方式的,但是奈何我找不到一種記錄的方式,在無奈之下,我找到了一種便於理解的演算法思想,

我們知道在java中,動態初始化的陣列預設值是0,我們可以用一個數組(recode[])來記錄在進行卡拉茲猜想過程中出現的數,然後給這個數對應的recode[i]賦值為1,那麼最後我們最後輸出我們輸入這些數中記錄值為0的就是關鍵數了,當時理解這個演算法時我驚了,這麼巧的辦法我咋沒有想到呢?哈哈哈哈哈,用陣列外的陣列來進行記錄,不得不佩服。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //輸入要判斷數字的個數
        int num = sc.nextInt();
        //動態初始化陣列
        int[] arr = new int[num];
        //將陣列迴圈輔助
        for (int x = 0; x < num; x++) {
            arr[x] = sc.nextInt();
        }
        //將輸入的數進行從小到大排序,方便自己在輸出是按從大到小輸出
        Arrays.sort(arr);
        //建立一個存放arr陣列的陣列,用來記錄進行猜想時出現的所有數
        int[] recode = new int[100];
        for (int x = 0; x < arr.length; x++) {
            //temp臨時存放輸入的數,和中間猜想出現的所有數
            int temp = arr[x];
            while (temp != 1) {
                if (temp % 2 == 0) {
                    temp /= 2;
                } else {
                    temp = (temp*3+1)/2;
                }
                //將猜想時出現過的數都記錄為1
                recode[temp] = 1;
            }
        }
        int Control_space = 0;
        //for迴圈逆序從大到小輸出符合題目要求的值
        for(int x=num-1;x>=0;x--) {
            //只有猜想時沒有出現過的數才被輸出,而且這些數是在arr陣列中的數
            if(recode[arr[x]]!=1){
                if (Control_space == 0) {
                    System.out.print(arr[x]);
                    Control_space = 1;
                } else {
                    System.out.print(" " + arr[x]);
                }
            }
        }

    }
}