原題目鏈接
題解和源碼
#include"stdio.h"
/* 最開始拿到這道題想嘗試用結構體求解,結構體中第一個元素為輸入的數字,第二個數字為
輸入數字進行3n+1猜想分解過程中的每一步,然后如果該數組中的數字在原始輸入的哪一組數中
出現,則該結構體中的數字不是關鍵數,然后寫了一堆代碼,發現太復雜了,后期還涉及排序,更
復雜了,題上最大數字不超過100,且還互不重復,一個大小為100的int數組就可解決,所謂覆蓋,
直接置零就完事
*/
int main()
{
int K,cur,num[101]={0};
//輸入的過程
/*只使用num的第2-101個位置,恰好100個;cur 表示當前讀入的數字*/
scanf("%d",&K);
for(int i=0;i<K;i++)
{ scanf("%d",&cur);
num[cur]=1;
}
//覆蓋的過程
for(int i=1;i<=100;i++)
{ if(num[i])
{ for(int j=i;j>1;)
/*將i的值賦給j,對j進行3n+1猜想*/
{ if(j%2){ j=(3*j+1)/2 ;}
else {j/=2;}
//判斷每操作一步后更新的j值是否被覆蓋
if(j<=100&&num[j])
/*這一步比較關鍵,首先得判斷j是否小于100,否則若直接判斷num[j]可能出現數組越界
eg. j=81==》j=122 發生越界*/
{ num[j]=0; //用置0的方式表示該數被覆蓋,最后剩下的數自然就是關鍵數了
K--;//表示還剩余的未被覆蓋的數字,后面會用K來控制輸出結構
if(j<i) { break; } //減小時間復雜度的關鍵一步,不過也比較難以理解
}
}
}
}
//輸出的過程
for(int i=100;i>=1;i--) //要求按從大到小的順序輸出,將數組倒過來即可
{ if(num[i])
{
printf("%d%c", i, --K ? ' ' : '\0');
/*PTA的輸出格式經常是要求數字與數字之間以空格隔開,最后一個輸出不帶空格*/
}
}
return 0;
}