简便满分解法:1005 继续(3n+1)猜想 (25分)
立志用更少的代碼做更高效的表達
Pat乙級題解匯總——>傳送門
卡拉茲(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
思路:打表, 定義一個數組置0, 按順序對每個數字都進行循環, 對期間的所有出現的數字置1, 最后只要輸出為0的就可以了。
具體見代碼。
注意: 數組要定義的大一些。
代碼展示
#include<iostream> #include<vector> #include<algorithm> using namespace std; int vis[300005];void While(int n) {while(n != 1) {if(n%2 == 0) { n/=2; vis[n]=1; } else { n = n*3+1; }} }int main() {vector<int>v;int n; cin>>n; while(n--) {int x; cin>>x;v.push_back(x); //存入vector,待會判斷時用 While(x); //打表循環 }sort(v.begin(), v.end(), greater<int>() ); //降序排序 int siz = v.size(); //要在這里定義,否則每次for循環都會計算一次 int T = 0;for(int i = 0; i < siz; i++) {if(vis[v[i]] == 0) {cout <<(T==0?"":" ") << v[i];T++;}} return 0; }每日一句
零星的變好,最后也會如星河般閃耀。
總結
以上是生活随笔為你收集整理的简便满分解法:1005 继续(3n+1)猜想 (25分)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简便解法:1004 成绩排名 (20分)
- 下一篇: 简洁易懂:c:out标签详解