zl程序教程

您现在的位置是:首页 >  其他

当前栏目

800. 数组元素的目标和(双指针,二分)

2023-04-18 15:37:48 时间

https://www.acwing.com/problem/content/802/
二分:
枚举a,
对于每一个a[i],都二分一下求x-a[i],是否在b数组中

#include<iostream>

using namespace std;

const int N = 1e5+10;

int n,m,x;
int a[N],b[N];
int ansx,ansy;
int main()
{
    cin >> n >> m >> x;
    for(int i=0;i<n;i++)cin >> a[i];
    for(int i=0;i<m;i++)cin >> b[i];
    for(int i=0;i<n;i++)
    {
        int y=x-a[i];//此时所求b数组的值
        //二分b数组,寻找满足的下标
        int l=0,r=m-1;
        while(l<=r)
        {
            int mid=l+r+1>>1;
            if(y==b[mid])
            {
                cout << i <<  << mid << endl;
                return 0;
            }
            else if(y>b[mid]) l=mid+1;
            else r=mid-1;
        }
    }
    
    return 0;
}

双指针:
首先考虑暴力:

for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
        if(a[i]+b[j]==x)
            find_ans

这样想:i从0~n,j从m-1~0,那么对于每一个i,j,判断是否满足(i,j)之和为x,这样j就不会像纯暴力那样会回溯了
那么就具有单调性,可以用双指针优化,类似夹逼定理,j变下,i变大

#include<iostream>

using namespace std;

const int N = 1e5+10;

int n,m,x;
int a[N],b[N];
int ansx,ansy;
int main()
{
    cin >> n >> m >> x;
    for(int i=0;i<n;i++)cin >> a[i];
    for(int i=0;i<m;i++)cin >> b[i];
    for(int i=0,j=m-1;i<n;i++)
    {
        
        while(j>=0 && a[i]+b[j]>x)j--;
        if(a[i]+b[j]==x)
        {
            cout << i <<  << j << endl;   
            return 0;
        }
    }
    return 0;
}