- 总时间限制:
- 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
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define maxn 100010 4 int a[maxn]; 5 int cmp(const void *a,const void *b) 6 { 7 return *(int *)a-*(int *)b; 8 } 9 int found(int l,int r,int tg) 10 { 11 int mid=(l+r)/2; 12 while(l<r-1) 13 { 14 if(tg==a[mid]) return 1; 15 else if(a[mid]>tg) r=mid; 16 else l=mid; 17 mid=(l+r)/2; 18 } 19 return 0; 20 } 21 int main() 22 { 23 int n; 24 int min; 25 int i,j; 26 int flag=0; 27 int sum; 28 int n1,n2; 29 int tg,l,r; 30 scanf("%d",&n); 31 scanf("%d",&a[0]); 32 min=a[0]; 33 for(i=1;i<n;i++) 34 { 35 scanf("%d",&a[i]); 36 if(a[i]<min) min=a[i]; 37 } 38 qsort(a,n,sizeof(int),cmp); //方便二分 39 scanf("%d",&sum); 40 if(n==1) flag=0; 41 else 42 { 43 j=0; 44 while(j<n) 45 { 46 tg=sum-min; 47 if(found(j,n,tg)) 48 { 49 flag=1; 50 n1=min;//a[j]==min 51 n2=tg; 52 break; 53 } 54 else 55 min=a[++j]; 56 } 57 } 58 if(flag==0) printf("No "); 59 else printf("%d %d ",n1,n2); 60 return 0; 61 }
这题其实它也不难,就是些二分的基本了。
首先要分析n=1的情况,这时只能No。
然后分析n>=2的情况。方法很简单,准备工作是快排,然后从第一个数开始,用给定数m减去当前选定的数a[j],用二分从当前数到最大数中找一找。