卡拉茲(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
#include<stdio.h>
#include<stdlib.h>
int *array;
void jugment(int a,int n){
int i;
int flag=1;
while(a!=1&&a!=0){
if(a%2==0)
a=a/2;
else
a=(3*a+1)/2;
for(i=0;i<n;i++){
if(a==array[i]){
array[i]=0;
}
}
}
}
void input(int n){
int i;
array=(int*)calloc(n,sizeof(int));
for(i=0;i<n;i++){
scanf("%d",&array[i]);
}
for(i=0;i<n;i++)
{
jugment(array[i],n);
}
}
void sort(int n){
int i,j,t;
for(i=0;i<n-1;i++){
for(j=0;j<n-1-i;j++){
if(array[j]<array[j+1]){
t=array[j];
array[j]=array[j+1];
array[j+1]=t;
}
}
}
}
void main(){
int n;
int i;
scanf("%d",&n);
input(n);
sort(n);
for(i=0;i<n;i++){
if(array[i]!=0){
if(array[i+1]==0||i==n-1)
printf("%d",array[i]);
else
printf("%d ",array[i]);
}
}
}
解析:
該題的具體思路就是在驗證每個數的時候,将每次參與計算的數字與數組中的數進行比較,如有相同(覆寫數)則将該數在數組中做一個标記(我這裡均記為0),最後數組裡沒有标記的數(關鍵數)輸出即可
注:
1.這裡的數組我采用了動态輸入,也可以根據題目限制直接定義動态數組array[100]
2.因為不想把數組傳來傳去,所有直接偷懶定義為了全局變量>_<
3.這道題是自己添來添去,随便憑感覺做出來的,應該不是最優解(在jugment()函數裡每進行一次計算都要周遊一次數組進行判斷,時間複雜度并不理想,不知道有沒有更好的解決辦法,歡迎各位同僚提供方案,共同讨論)