双指针问题,先想想暴力怎么做
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i]+b[j]==x)
cout<<i<<' '<<j;
暴力出来了,但是时间复杂度太高了,需要优化
注意到a,b数组是具有单调性的
1.a,b都单调递增
i=0时,枚举到6,不满足条件,跳出 a[i]=1,b[j]=6
i=1时,j不变仍是6,不满足条件,跳出 a[i]=2,b[j]=6
...
我们可以发现,当a,b都单调递增时,枚举到第一个不满足条件的j时,这个j可能会导致可以与i+1匹配的j-1无法被枚举到,导致答案出错
2.a单调递增,b单调递减
由于a,b都是从小到大排序,所以让i=0,j=m-1
对于第一个跳出循环的i,j (即a[i]+b[j]>=x),此时可以保证
a[i+1]+(b[j]~b[m-1])任意一个数都是不满足循环条件(<=x)的
a[i+1]+b[j~m-1] >=x
所以不会丢失合法答案
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+10;
int a[N];
int b[N];
int main()
{
int n,m,x;
cin>>n>>m>>x;
for(int i=0;i<n;i++)
cin>>a[i];
for(int j=0;j<m;j++)
cin>>b[j];
for(int i=0,j=m-1;i<n;)
{
while(j>=0&&a[i]+b[j]>x)
j--;
if(a[i]+b[j]==x)
cout<<i<<' '<<j;
i++;
}
return 0;
}