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

PAT-乙級-1005 繼續(3n+1)猜想

避免 names iostream base clu 測試 順序輸出 math problem

卡拉茲(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<n100)的值,數字間用空格隔開。

輸出格式:

每個測試用例的輸出占一行,按從大到小的順序輸出關鍵數字。數字間用 1 個空格隔開,但一行中最後一個數字後沒有空格。

輸入樣例:

6
3 5 6 7 8 11

輸出樣例:

7 6


分析:
  遍歷給出的列表,將每個數的覆蓋數從列表中剔除

  剩下的數排序即可
  PS:如果用集合更簡單

 1 //c++
 2 #include<iostream>
 3 using namespace
std; 4 5 int main(){ 6 int n; 7 cin>>n; 8 int arr[n]; 9 for(int i=0;i<n;i++) 10 cin>>arr[i]; 11 for(int i=0;i<n;i++){ 12 if(arr[i]==0) 13 continue; 14 int tmp=arr[i]; 15 while(tmp!=1){ 16 if(tmp%2) 17 tmp=(tmp*3+1)/2; 18 else 19
tmp/=2; 20 for(int j=0;j<n;j++){ 21 if(arr[j]==tmp){ 22 arr[j]=0; 23 break; 24 } 25 } 26 } 27 } 28 int flag; 29 for(int i=0;i<n-1;i++){ 30 flag=1; 31 for(int j=0;j<n-i-1;j++){ 32 if(arr[j]<arr[j+1]){ 33 int tmp=arr[j]; 34 arr[j]=arr[j+1]; 35 arr[j+1]=tmp; 36 flag=0; 37 } 38 } 39 if(flag) 40 break; 41 } 42 for(int i=0;arr[i]!=0;i++){ 43 if(i) 44 cout<< ; 45 cout<<arr[i]; 46 } 47 return 0; 48 }

PAT-乙級-1005 繼續(3n+1)猜想