和為給定數(二分法)

破刀發表於2024-04-06

題目:


描述
給出若干個整數,詢問其中是否有一對數的和等於給定的數。

輸入
共三行:

第一行是整數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)

優先順序從上到下依次遞減,最上面具有最高的優先順序,逗號運算子具有最低的優先順序。
相同優先順序中,按結合順序計算。大多數運算是從左至右計算,只有三個優先順序是從右至左結合的,它們是單目運算子條件運算子賦值運算子
基本的優先順序需要記住:
指標最優,單目運算優於雙目運算。如正負號。
先乘除(模),後加減。
先算術運算,後移位運算,最後位運算。請特別注意:1 << 3 + 2 & 7等價於 (1 << (3 + 2))&7.
邏輯運算最後計算。

果然 我還是又wrong了。。。

4、原來我開始定義的long long 格式化卻用的%d。。。。

相關文章