题目描述

分析:
解法1:利用散列表记录数字的个数即可,判断i和m-i是否都存在,注意假如i==m-i则要判断i出现的次数是否大于等于2
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int HashTable[1005];
int main(){
int n,m;
cin>>n>>m;
int a;
while(n--){
cin>>a;
HashTable[a]++;
}
for(int i=0;i<1005;i++){
if(HashTable[i]&&HashTable[m-i]){
if(i==m-i&&HashTable[i]<=1)
continue;
cout<<i<<" "<<m-i<<endl;
return 0;
}
}
cout<<"No Solution"<<endl;
return 0;
}
解法2:二分查找
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100005];
int binarySearch(int l,int r,int key){
int mid;
while(l<=r){
mid=(l+r)/2;
if(a[mid]==key){
return mid;
}
else if(a[mid]>key) {
r=mid-1;
}
else{
l=mid+1;
}
}
return -1;
}
int main(){
int n,m,i;
scanf("%d %d",&n,&m);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
for(i=0;i<n;i++){
int pos=binarySearch(0,n-1,m-a[i]);
if(pos!=-1&&i!=pos){
printf("%d %d",a[i],m-a[i]);
break;
}
}
if(i==n)
printf("No Solution\n");
return 0;
}
解法3:双指针法
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100005];
void twoPointers(int n,int m){
int i=0;
int j=n-1;
while(i<j){
if(a[i]+a[j]==m) break;
else if(a[i]+a[j]<m){
i++;
}
else{
j--;
}
}
if(i<j){
printf("%d %d\n",a[i],a[j]);
}
else{
printf("No Solution\n");
}
}
int main(){
int n,m,i;
scanf("%d %d",&n,&m);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
twoPointers(n,m);
return 0;
}