卡拉茲(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
#include
#include
#define UNCOVERED 1
#define COVERED -1
using namespace std;
int fun(int m){
if(m%2==0){
m=m/2;
}
else{
m=(3*m+1)/2;
}
return m;
}
int main()
{
int k=0;
cin>>k;
vector metlist;
vector status;
vector inbuffer;
for(int i=0;i>n;
inbuffer.push_back(n);
//check n in met list
vector::iterator result_n = find(metlist.begin(),metlist.end(),n);
//if exist continue for
if(result_n!=metlist.end()){
continue;
}
//else put n into met list
else{
metlist.push_back(n);
//set status uncovered
status.push_back(UNCOVERED);
int m=n;
//do m=f(m,3m+1)
while((m=fun(m))!=1){
//check status of m
vector::iterator result_m = find(metlist.begin(),metlist.end(),m);
if(result_m==metlist.end()){//not found
metlist.push_back(m);
status.push_back(COVERED);//covered
}
else{
*(result_m-metlist.begin()+status.begin())=COVERED;//change to covered
break;//break while
}
}//end while
}//end else
}//end for
vector outbuffer;
for(int i=0;i::iterator index = find(metlist.begin(),metlist.end(),inbuffer[i]);
if(index!=metlist.end()){
if(*(index-metlist.begin()+status.begin())==UNCOVERED){
outbuffer.push_back(inbuffer[i]);
}
}
}
sort(outbuffer.begin(),outbuffer.end(),greater());
cout<