和為給定數(二分)


07:和為給定數

總時間限制: 
1000ms
 
內存限制: 
65536kB
描述

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

輸入
共三行:
第一行是整數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

【思路】

# 結果 時間
14 Accepted 03-28
13 Accepted 03-28
12 Accepted 03-28
11 Time Limit Exceeded 03-28
10 Accepted 03-28
9 Wrong Answer 03-28
8 Time Limit Exceeded 03-28
7 Wrong Answer 03-28
6 Runtime Error 03-28
5 Runtime Error 03-28
4 Runtime Error 03-28
3 Wrong Answer 03-28
2 Compile Error 03-27
1 Wrong Answer 03-27

讓爸爸用血與淚的經歷告訴你們這道題的思路orz

開始 我是這樣想的 從那些數中 找出一個比給定數小一位的數,然后找m-比他小一位的數是否在序列中,但是還要判斷比他小一位的數

是否在序列中等諸多問題(orz),然后就wrong了

后來 題解 的方法是將序列按升序排序,從第一位開始,看看m-第一位是否在序列中。。正好與我相反(orz)

然后又wrong了QAQ

有個坑 如果 2個數 1 3 給定數為2,那么就會輸出1 1,這是不對的,1重復使用了。所以還要判斷重復使用。在二分查找的時候,函數的返回值是他的位置

並且找到的這個位置不能等於他正在枚舉的數的位置,這樣就避免了、、、、

但是 又 wrong了

原來 是 移位運算的順序0-0

l+(r-l)/2 這是我的本意 然后我用了移位運算 l+(r-l)>>1,這樣是不對的 

因為 (下面貼一大段qwq)

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

果然 我還是又wrong了。。。

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

最后

accepted

end(orz) 

【代碼】
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,m;
 7 int a[100009];
 8 int   f(int);
 9 int main()
10 {
11     scanf("%d",&n);
12     for(int i=1;i<=n;i++)
13     scanf("%d",&a[i]);
14     scanf("%d",&m);
15     sort(a+1,a+n+1);//排序 
16     for(int i=1;a[i]<=m/2;i++)//枚舉m/2前面的數(這樣循環次數會少,因為m/2總有一個數滿足) 
17     {
18         if(f(m-a[i])&&f(m-a[i])!=i)//能找到這個數並且沒有重復使用 
19         {
20             printf("%d %d",a[i],m-a[i]);
21             return 0;
22         }
23     }
24     printf("No");
25     return 0;
26 }
27 int f(int  x)// 返回位置 
28 {
29     int  l=1,r=n,mid;
30     while(l<=r)
31     {
32         mid=l+((r-l)>>1);//>>1是除以2。不用(l+r)/2是為了避免l+r數據過大 
33         if(a[mid]==x)return mid;
34         if(a[mid]<x)l=mid+1;
35         if(a[mid]>x)r=mid-1;
36     }
37     return 0;
38 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM