日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PAT1005 继续(3n+1)猜想 (25 分)【vector erase需要注意的地方】

發布時間:2024/2/28 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PAT1005 继续(3n+1)猜想 (25 分)【vector erase需要注意的地方】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

心得

無論在任何時候,使用vector的erase方法時需要謹慎再謹慎。
無論是使用數組的形式arr[i]進行遍歷,還是使用iter迭代器遍歷,在使用erase后,原來的位置都可能會失效。因為這種遍歷刪除可能會觸碰到當前元素i(或iter)之前的元素,也就改變了i(或者iter)的絕對位置,雖然i沒變,但是arr[i]指向的數變了!
這導致跳過了某些vector arr數值沒有判斷,或者直接iter失效,也就是將一個無效的值賦值給了將無效函數視為嚴重錯誤的函數。

對于本體的解法,原思路的bug在于,如果刪除了一個i之前的元素,會讓i的絕對位置后移一位,跳過了之前那一位的判斷。

因此在本題中的解決方法是:迷之25行的對于debugger定義

將錯就錯,跳過一個判斷就跳過判斷吧,就暫且讓那些該被刪除的數多活一個循環。以后在處理這些數也不晚。
我把整個過程重復arr.size()次,就算是每次都跳過了一個arr[i]的判斷,但至少在這次中肯定會至少刪除一個該刪的元素。然后重復arr.size()次以后,那些被跳過的也補回來了。

其他解決方法
其他方法解決vector中刪除的元素當前元素之前的元素的問題:
1.用鏈表,pcur指向當前元素(絕對位置)。指針的位置不會因為刪除任何位置的元素而改變。
2.賦異常值。如果刪除一個元素,將這個元素賦值為-1,最后再遍歷刪除所有值為-1的元素(原理同樣是保持相對位置或者說絕對位置不變)
3.動態調整i
刪除元素的時候,如果要刪除的元素的位置j<i,則i--

題目

卡拉茲(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

代碼

//把每一個元素都算一遍,過程中遇到的數如果有和給定數組中相同的,刪除數組中的數。這樣,數組中最后剩下的就是關鍵數 #define _CRT_SRCURE_NO_WARNINS #include<iostream> #include<vector> #include<algorithm> using namespace std; int main() {int total;cin >> total;//輸入vectorvector<int>arr;int num;int i;for (i = 0; i < total; i++){cin >> num;arr.push_back(num);}//計算每個元素,刪除重復的sort(arr.begin(), arr.end());int n;int j;int debugger = arr.size();for (; debugger >= 0; debugger--){for (i = 0; i < arr.size(); i++){//計算nn = arr[i];while (n != 1){if (n % 2 == 0){n /= 2;}else{n = (3 * n + 1) / 2;}//刪除n(不能刪除a[i]本身,但不避免a[i]重復的可能)for (j = 0; j < arr.size(); j++){if (arr[j] == n ){arr.erase(arr.begin() + j);}}}}}//刪除重復元素sort(arr.begin(), arr.end()); //unique只能比較相鄰元素是否重復arr.erase(unique(arr.begin(), arr.end()), arr.end()); //unique將重復的元素移到末尾,返回末尾中第一個重復值的地址//21//3 5 6 7 8 11 12 4 5 6 7 8 9 10 11 12 13 14 15 16 17for (i = arr.size() - 1; i >= 0; i--){cout << arr[i];if (i != 0)cout << ' ';}system("pause");return 0; }

總結

以上是生活随笔為你收集整理的PAT1005 继续(3n+1)猜想 (25 分)【vector erase需要注意的地方】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。