PTA-乙級1005 繼續(3n+1)猜想 (25 分)-JAVA
阿新 • • 發佈:2021-10-22
為了方便看題,這裡給出卡拉茲猜想:
卡拉茲(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]); } } } } }