题目要求:
给出 正整数m和n个正整数(num1,num2,…,num n),让你求出( num i + num j ==m)的方案,若方案不唯一,要求输出num i 最小的方案。
三种方法:
- 用hashTable记录每个数字出现的次数,从i开始枚举,如果hashTable[i[>0&&hashTable[j]>0&&(i+j>=2),则输出。(要注意i=j且次数等于1的情况)
- 排序+二分,用 lower_bound函数。
- two pointers
方法一:hashTable:
#include<cstdio>
#include<algorithm>
using namespace std;
int const MAXN = 100010,MAXM = 1010;
int hashTable[MAXM] = {0};
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
int t;
scanf("%d",&t);
hashTable[t]++;
}
for(int i=0;i<m;i++)
{
if(hashTable[i]>0&&hashTable[m-i]>0)
{
if(i==m-i&&hashTable[i]<2)
continue;
printf("%d %d",i,m-i);
return 0;
}
}
printf("No Solution");
return 0;
}
方法二:二分
/*Sample Input 1:
8 15
1 2 8 7 2 4 11 15----------------
4 11
Sample Input 2:
7 14
1 8 7 2 4 11 15---------------
No Solution*/
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 100010;
int n,m;
int a[maxn] = {0};
int main()
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
for(int i=0;i<n;i++)
{
//二分法查找第一个大于等于m-a[i]的数字
int t=a[i];
int* j = lower_bound(a+i+1,a+n,m-t);
if(a[i]+*j==m&&i!=n-1)
{
printf("%d %d",a[i],*j);
return 0;
}
}
printf("No Solution");
return 0;
}
方法3:two pointers
/*Sample Input 1:
8 15
1 2 8 7 2 4 11 15
Sample Output 1:
4 11*/
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 100010;
int a[maxn]={0};
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
int i=0,j=n-1;
while(i<j)
{
if(a[i]+a[j]==m)
{
cout<<a[i]<<" "<<a[j];
return 0;
}
if(a[i]+a[j]<m)
i++;
else if(a[i]+a[j]>m)
j--;
}
cout<<"No Solution";
return 0;
}