问题描述
输入 n(n≤1000,000) 个整数,找出其中的两个数,他们之和等于整数 m (假定肯定有解)。所有数都能用int表示
输入格式
第一行: 一个整数 n 表示有多少个数;
第二行: n 个整数,用空格隔开;
第三行: 一个整数 m。
输出格式
从小到大,输出所有的组合方案。
一行输出一组方案,用空格隔开;
样例
输入数据 1
9
21 4 5 6 13 65 32 9 23
28
Copy
输出数据 1
5 23
1:方法解析
L3/L4 尺取法
尺取法
科普一下,尺取法有两种形式,分别为反向扫描反向扫描和同向扫描同向扫描,
!相对着扫描,叫做反向扫描;核心代码为:
// 尺取法-反向扫描
while(i < j){
// if(.....)
i++;
// if(.....)
j--;
}
再看这两个人,他们沿同一方向运动,所以是同向扫描,核心代码:
// 尺取法-同向扫描
int i2 = 1, j2 = 1;
while(j < n){
// if(......)
i2++;
// if(.....)
j2++;
}
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, a[N], c;
int main(){
cin >> n;
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
cin >> c;
sort(a+1,a+n+1);// 1.进行排序
int l = 1, r = n;// 反向寻找,一个头,一个尾
while(l < r){// 只要头尾不重合
int sum = a[l] + a[r];
if(sum == c) {
cout << a[l] << " " << a[r] << endl;
l++;
}else if(sum > c) {
r--;// 如果结果大了,右边调小一点
}else if(sum < c){
l++;// 如果结果小了,左边大一些
}
}
return 0;
}