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 }