題目:
描述
給出若干個整數,詢問其中是否有一對數的和等於給定的數。
輸入
共三行:
第一行是整數n(0 < n <= 100,000),表示有n個整數。
第二行是n個整數。整數的範圍是在0到10^8之間。
第三行是一個整數m(0 <= m <= 2^30),表示需要得到的和。
輸出
若存在和為m的數對,輸出兩個整數,小的在前,大的在後,中間用單個空格隔開。若有多個數對滿足條件,選擇數對中較小的數更小的。若找不到符合要求的數對,輸出一行No。
樣例輸入
4
2 5 1 4
6
樣例輸出
1 5
解題思路
定義一個標誌,預設值為0
把陣列按從小到大排序
寫一個for迴圈對陣列的每一項進行遍歷,在for迴圈中利用二分查詢查詢在剩餘的每一項中是否有和為給定的數,如果有給標誌賦值1,並跳出迴圈
for迴圈結束後如果標誌值仍然為0,則輸出No
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 int f = 0; //標誌數 6 7 int main() 8 { 9 int n,m; 10 cin >> n; 11 int num[n]; 12 for(int i = 0; i < n; i++){ 13 cin >> num[i]; 14 } 15 cin >> m; 16 17 sort(num, num + n); //對陣列進行升序排序 18 19 for(int i = 0; i < n; i++){ 20 int left = i + 1, right = n; 21 while(left < right){ 22 int mid = (left + right) / 2; 23 //找到給定值輸出結果並結束迴圈 24 if(num[mid] + num[i] == m){ 25 f = 1; 26 cout << num[i] << " " << num[mid] << endl; 27 break; 28 } 29 if(num[i] + num[mid] < m){ 30 left = mid + 1; 31 } 32 else{ 33 right = mid - 1; 34 } 35 } 36 if(f == 1) break; //如果標誌為1代表已經輸出了需要的結果,無需後續遍歷 37 } 38 39 //未找到給定數 40 if(f == 0){ 41 cout << "No" << endl; 42 } 43 44 return 0; 45 }
————————————————
版權宣告:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。
原文連結:https://blog.csdn.net/m0_51684823/article/details/129189796
-------------------------------------------------
中間的坑
用血與淚的經歷告訴你們這道題的思路orz
1、開始 我是這樣想的 從那些數中 找出一個比給定數小一位的數,然後找m-比他小一位的數是否在序列中,但是還要判斷比他小一位的數
是否在序列中等諸多問題(orz),然後就wrong了
後來 題解 的方法是將序列按升序排序,從第一位開始,看看m-第一位是否在序列中。。正好與我相反(orz)
然後又wrong了QAQ
2、有個坑 如果 2個數 1 3 給定數為2,那麼就會輸出1 1,這是不對的,1重複使用了。所以還要判斷重複使用。在二分查詢的時候,函式的返回值是他的位置
並且找到的這個位置不能等於他正在列舉的數的位置,這樣就避免了、、、、
但是 又 wrong了
3、原來 是 移位運算的順序0-0
l+(r-l)/2 這是我的本意 然後我用了移位運算 l+(r-l)>>1,這樣是不對的
因為 (下面貼一大段qwq)
果然 我還是又wrong了。。。
4、原來我開始定義的long long 格式化卻用的%d。。。。