原題:
卡拉茲(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<n<=100)的值,數字間用空格隔開。
輸出格式:每個測試用例的輸出占一行,按從大到小的順序輸出關鍵數字。數字間用1個空格隔開,但一行中最后一個數字后沒有空格。
輸入樣例:
6 3 5 6 7 8 11
輸出樣例:
7 6
我的理解:
這道題主要是對題意得分析,搞清楚“關鍵數"的定義,
就是該數不會出現在判斷數組中某個數是否滿足卡拉茲猜想的過程中。
搞清楚這個,那接下來就簡單了。
首先找出判斷某個數滿足猜想過程中出現的所有數
然后讓原數組中的數和上一步出現的所有數一一比較,
只要數組中出現相同匹配的數就想辦法把這個數從數組剔除,
最后排序輸出就行
code
1 #include<stdio.h> 2 #include<malloc.h> 3 4 void sort(int *,int ); 5 int main() 6 { 7 int *a; 8 int n,i,t,j; 9 scanf("%d",&n); 10 a=(int*)malloc(n*sizeof(int)); // 動態申請數組空間 11 for(i=0;i<n;i++) 12 { 13 scanf("%d",&a[i]); 14 } 15 for(i=0;i<n;i++) 16 { 17 t=a[i]; 18 if(t==0) 19 continue;//碰到數組中有0的項,則跳過 20 while(t!=1) 21 { 22 if(t%2==0) 23 t/=2; 24 else 25 t=(3*t+1)/2; 26 for(j=0;j<n;j++)//數組中所有數與運算中出現的數比較 27 { 28 if(a[j]==t)//如果數組中有和運算過程中相同的數,就把數組中的該數改為0 29 { 30 a[j]=0; 31 break;//因為輸入的數組是互不相同的數,所以不會存在有多個匹配的情況,找到有一個匹配就可跳出,以節省內存減少運行時間。 32 } 33 } 34 35 } 36 37 } 38 sort(a,n);//排序 39 for(i=0;a[i]>0;i++) 40 { 41 printf("%d%s",a[i],a[i+1]>0?" ":""); 42 } 43 } 44 void sort(int *P,int K) //排序 45 { 46 int i,j,temp; 47 for(i=0;i<K;i++) 48 for(j=i+1;j<K;j++) 49 { 50 51 if(P[i]<P[j]) 52 { 53 temp=P[i]; 54 P[i]=P[j]; 55 P[j]=temp; 56 } 57 } 58 }