當我們驗證卡拉茲猜想的時候钠乏,為了避免重復計算栖秕,可以記錄下遞推過程中遇到的每一個數(shù)。例如對 n=3 進行驗證的時候晓避,我們需要計算 3簇捍、5、8俏拱、4暑塑、2、1锅必,則當我們對 n=5事格、8、4况毅、2 進行驗證的時候分蓖,就可以直接判定卡拉茲猜想的真?zhèn)味В恍枰貜陀嬎愣恚驗檫@ 4 個數(shù)已經(jīng)在驗證3的時候遇到過了,我們稱 5终娃、8味廊、4、2 是被 3“覆蓋”的數(shù)棠耕。我們稱一個數(shù)列中的某個數(shù) n 為“關鍵數(shù)”余佛,如果 n 不能被數(shù)列中的其他數(shù)字所覆蓋。
現(xiàn)在給定一系列待驗證的數(shù)字窍荧,我們只需要驗證其中的幾個關鍵數(shù)辉巡,就可以不必再重復驗證余下的數(shù)字。你的任務就是找出這些關鍵數(shù)字蕊退,并按從大到小的順序輸出它們郊楣。
輸入格式:
每個測試輸入包含 1 個測試用例,第 1 行給出一個正整數(shù) K (<100)瓤荔,第 2 行給出 K 個互不相同的待驗證的正整數(shù) n (1<n≤100)的值净蚤,數(shù)字間用空格隔開。
輸出格式:
每個測試用例的輸出占一行输硝,按從大到小的順序輸出關鍵數(shù)字今瀑。數(shù)字間用 1 個空格隔開,但一行中最后一個數(shù)字后沒有空格。
輸入樣例:
6
3 5 6 7 8 11
輸出樣例:
7 6
思路:得到一個數(shù)字列表橘荠,對每一個數(shù)字都設置一個狀態(tài)位屿附,初始為true。遍歷每個數(shù)字的覆蓋數(shù)字砾医,用覆蓋數(shù)字比對其他數(shù)字拿撩,如果有相等的,其他數(shù)字的狀態(tài)位設置false如蚜。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int numb;
cin>>numb;
vector<int> nums;
vector<bool> flags;
for(int i=0;i<numb;i++)
{
int num;
cin>>num;
nums.push_back(num);
flags.push_back(true);
}
for(int i=0;i<numb;i++)
{
vector<int> temp;
int theN=nums[i];
while(theN!=1)
{
if(theN%2==0)
{
theN=theN/2;
temp.push_back(theN);
}else
{
theN=(3*theN+1)/2;
temp.push_back(theN);
}
}
for(int j=0;j<temp.size();j++)
{
for(int k=0;k<numb;k++)
{
if(nums[k]!=theN)
{
if(temp[j]==nums[k])
flags[k]=false;
}
}
}
}
vector<int> res;
for(int i=0;i<numb;i++)
{
if(flags[i])
res.push_back(nums[i]);
}
for(int i=0;i<res.size()-1;i++)
{
for(int j=0;j<res.size()-i-1;j++)
{
if(res[j]<res[j+1])
{
int temp=res[j];
res[j]=res[j+1];
res[j+1]=temp;
}
}
}
for(int i=0;i<res.size()-1;i++)
{
cout<<res[i]<<" ";
}
cout<<res[res.size()-1];
return 0;
}