標籤:value using namespace eve log 測試 span pat color
1005. 繼續(3n+1)猜想 (25)時間限制400 ms記憶體限制65536 kB代碼長度限制8000 B判題程式Standard作者CHEN, Yue
卡拉茲(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個空格隔開,但一行中最後一個數字後沒有空格。
輸入範例:
63 5 6 7 8 11
輸出範例:
7 6
思路:建造兩個set容器,s1儲存所有數變為1過程中產生的數,s2則儲存關鍵數
注意點:後續輸入的數覆蓋了前面的數,所以需要判斷變為1的過程中是否包含了關鍵數中的關鍵數,如果有,將這個關鍵數刪除
1 // 1005.cpp : 定義控制台應用程式的進入點。 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 9 using namespace std;10 11 void get_num(int n, set<int>& s1, set<int>& s2);12 13 int main()14 {15 int N,temp;16 17 //s1為所有輸入的數變成1過程中產生的數18 //s2為關鍵數19 set<int> s1,s2;20 21 cin >> N;22 23 for (int i = 0; i < N; ++i)24 {25 cin >> temp;26 27 //如果輸入的數沒有被其他的數覆蓋28 if (find(s1.begin(), s1.end(), temp) == s1.end())29 {30 s2.insert(temp);31 get_num(temp, s1, s2);32 }33 }34 35 set<int>::reverse_iterator i,end = s2.rend();36 37 for (i = s2.rbegin(); i != end; ++i)38 {39 if (i == s2.rbegin())40 cout << *i;41 else42 cout << " " << *i;43 }44 45 cout << endl;46 47 return 0;48 }49 50 void get_num(int n,set<int>& s1,set<int>& s2)51 {52 int i;53 54 s1.insert(n);//將該數也插入容器中,防止後面的數覆蓋此數而未檢查到55 56 while (n != 1)57 {58 if (n & 1)59 n = 3 * n + 1;60 61 n /= 2;//無論奇偶都會除以262 63 if (find(s2.begin(), s2.end(), n)!=s2.end())64 {65 s2.erase(n);//如果該數覆蓋前面的數,則將前面的數從關鍵數容器刪除66 67 break;68 }69 70 s1.insert(n);71 }72 }
PAT 乙級 1005 繼續(3n+1)猜想 (25) C++版