題目描述:數組
卡拉茲(Callatz)猜測已經在1001中給出了描述。在這個題目裏,狀況稍微有些複雜。 當咱們驗證卡拉茲猜測的時候,爲了不重複計算,能夠記錄下遞推過程當中遇到的每個數。例如對 n=3 進行驗證的時候,咱們須要計算 三、五、八、四、二、1,
則當咱們對 n=五、八、四、2 進行驗證的時候,就能夠直接斷定卡拉茲猜測的真僞,而不須要重複計算,由於這 4 個數已經在驗證3的時候遇到過了,
咱們稱 五、八、四、2 是被 3「覆蓋」的數。咱們稱一個數列中的某個數 n 爲「關鍵數」,若是 n 不能被數列中的其餘數字所覆蓋。 如今給定一系列待驗證的數字,咱們只須要驗證其中的幾個關鍵數,就能夠沒必要再重複驗證餘下的數字。你的任務就是找出這些關鍵數字,並按從大到小的順序輸出它們。 輸入格式: 每一個測試輸入包含 1 個測試用例,第 1 行給出一個正整數 K (<100),第 2 行給出 K 個互不相同的待驗證的正整數 n (1<n≤100)的值,數字間用空格隔開。 輸出格式: 每一個測試用例的輸出佔一行,按從大到小的順序輸出關鍵數字。數字間用 1 個空格隔開,但一行中最後一個數字後沒有空格。
輸入樣例: 6 3 5 6 7 8 11 輸出樣例: 7 6
主要思想:測試
利用一個數組,初始置零,用於標記某個數字是否爲關鍵數; 並在運算過程當中添加一個計數器,記錄關鍵數的個數; 最後,倒序遍歷數組,若是標記爲1則打印輸出關鍵字。
本人代碼:spa
// Guess Number from 3*n+1 -> 1 // Go ahead // 這種解法(22/25) 最後一個測試點過不去 // 上述問題已經解決,在代碼 47行,48行給出了部分解釋 /* 當咱們驗證卡拉茲猜測的時候,爲了不重複計算, 能夠記錄下遞推過程當中遇到的每個數。例如對 n=3 進行驗證的時候, 咱們須要計算 三、五、八、四、二、1,則當咱們對 n=五、八、四、2 進行驗證的時候, 就能夠直接斷定卡拉茲猜測的真僞,而不須要重複計算, 由於這 4 個數已經在驗證3的時候遇到過了, 咱們稱 五、八、四、2 是被 3「覆蓋」的數。咱們稱一個數列中的某個數 n 爲「關鍵數」, 若是 n 不能被數列中的其餘數字所覆蓋。 如今給定一系列待驗證的數字,咱們只須要驗證其中的幾個關鍵數, 就能夠沒必要再重複驗證餘下的數字。 你的任務就是找出這些關鍵數字,並按從大到小的順序輸出它們。 */ # include <stdio.h> int main(void) { int k; // 輸入一個整數 k<100 int n, temp; int i; int table[101] = {0}; // 記錄數據是否出現 (不用再單獨排序) // 定義爲300 不會出現數組越界的狀況 int val = 0; // 記錄 最終table 中有多少個不爲零的數 scanf("%d",&k); for (i=0; i<k; i++) { scanf("%d",&temp); table[temp] = 1; } for (i=1; i<=100; i++) { // 若是此數字在table中出現過,則進行運算 if (1 == table[i]) { n = i; while(n>1) { if (n%2 == 0) n = n/2; else n = ((3*n)+1)/2; // 若是此處寫 n = 3*n+1 則會在最後一個測試點沒法經過,沒有仔細的看數字猜測過程,(3*n+1)/2 // 判斷計算過程當中的數是否在輸入數組中出現 // 注:在提交過程當中 若是直接判斷 table[n] (n==100)可能會出現數組越界的狀況 if (n<=100 && n>=2) { table[n] = 0; } } } } // 輸出table中不爲0 的下標的個數 for (i=100; i>=1; i--) { if (1 == table[i]) val++; } for (i=100; i>=1; i--) { if (1==table[i]) { printf("%d",i); val--; if (val != 0) printf(" "); } } return 0; }