卡拉茲(Callatz)猜測已經在1001中給出了描述。在這個題目裏,狀況稍微有些複雜。html
當咱們驗證卡拉茲猜測的時候,爲了不重複計算,能夠記錄下遞推過程當中遇到的每個數。例如對 n=3 進行驗證的時候,咱們須要計算 三、五、八、四、二、1,則當咱們對 n=五、八、四、2 進行驗證的時候,就能夠直接斷定卡拉茲猜測的真僞,而不須要重複計算,由於這 4 個數已經在驗證3的時候遇到過了,咱們稱 五、八、四、2 是被 3「覆蓋」的數。咱們稱一個數列中的某個數 n 爲「關鍵數」,若是 n 不能被數列中的其餘數字所覆蓋。ios
如今給定一系列待驗證的數字,咱們只須要驗證其中的幾個關鍵數,就能夠沒必要再重複驗證餘下的數字。你的任務就是找出這些關鍵數字,並按從大到小的順序輸出它們。數組
每一個測試輸入包含 1 個測試用例,第 1 行給出一個正整數 K (<),第 2 行給出 K 個互不相同的待驗證的正整數 n (1)的值,數字間用空格隔開。測試
每一個測試用例的輸出佔一行,按從大到小的順序輸出關鍵數字。數字間用 1 個空格隔開,但一行中最後一個數字後沒有空格。flex
6 3 5 6 7 8 11
7 6
建立一個足夠大的數組 recover_arr[MAXSIZE] (初始化爲0),對每一個輸入的數字進行驗證(3n+1猜測的步驟),驗證過的數字i令 recover_arr[i] = 1 (標記爲1),最後對這些輸入的數字從大到小排序,輸出 recover_arr[arr[i]] == 0; 的數字就能夠了
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #define MAXSIZE 10000 5 using namespace std; 6 7 8 9 int main() 10 { 11 int n; 12 vector<int> arr; 13 int recover_arr[MAXSIZE] = { 0 }; 14 cin >> n; 15 int temp_input = 0; 16 for (int i = 0; i < n; ++i) 17 { 18 cin >> temp_input; 19 arr.push_back(temp_input); 20 int temp = arr[i]; 21 while (temp != 1) 22 { 23 if (temp % 2 == 0) 24 { 25 temp /= 2; 26 } 27 else 28 { 29 temp = (3 * temp + 1) / 2; 30 } 31 recover_arr[temp] = 1; 32 } 33 } 34 sort(arr.begin(), arr.end()); //從小到大排序 35 reverse(arr.begin(), arr.end()); //將數組逆序,從大到小排序 36 int flag = 0; 37 for (int i = 0; i < n; ++i) 38 { 39 if (recover_arr[arr[i]] != 1) 40 { 41 if (flag == 1) 42 { 43 cout << " "; 44 } 45 cout << arr[i]; 46 flag = 1; 47 } 48 } 49 return 0; 50 }