• acwing800. 数组元素的目标和


    给定两个升序排序的有序数组 A 和 B,以及一个目标值 x。
    数组下标从 0 开始。
    请你求出满足 A[i]+B[j]=x 的数对 (i,j)。
    数据保证有唯一解。

    输入格式

    第一行包含三个整数 n,m,x,分别表示 A 的长度,B 的长度以及目标值 x。
    第二行包含 n 个整数,表示数组 A。
    第三行包含 m 个整数,表示数组 B。

    输出格式

    共一行,包含两个整数 i 和 j。

    数据范围

    数组长度不超过 10^5。
    同一数组内元素各不相同。
    1≤数组元素≤10^9

    输入样例:

    4 5 6
    1 2 4 7
    3 4 6 8 9
    

    输出样例:

    1 1
    

    一开始想了比如借助hashmap、一个顺序一个二分...艹,这题肯定不是想考这个啊。后来想到一个从0开始一个从m-1开始不就行了

    方法一:

    思路:双指针,初始A[i=0],B[j=m-1]

    1. x == A[i] + B[j],输出
    2. x < A[i] + B[j],因为数组是升序的,所以要i--j--,此时 i 再减就溢出了,所以让 j--
    3. x > A[i] + B[j],同理,让 i++

    补充:为什么这样不会漏情况呢

    1. 原因一:根据上面的思路,如果某次由于x > A[i] + B[j] i++ 后,变成了x < A[i] + B[j],此时可以选择i--j--,如果 i-- 的话,那不就是打回原形原地反复横跳吗23333,所以要进行 j--
    2. 原因二:所以,如果一个指针到达了最终位置,那么接下来移动的肯定是另一个指针,最终也会到达正确的位置
    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n, m, x;
    int a[100010], b[100010];
    
    int main() {
        scanf("%d%d%d", &n, &m, &x);
        for (int i = 0; i < n; i++) scanf("%d", &a[i]);
        for (int i = 0; i < m; i++) scanf("%d", &b[i]);
        int i = 0, j = m - 1, t = a[i] + b[j];
        while (t != x) {
            if (t > x) j--;
            else i++;
            t = a[i] + b[j];
        }
        printf("%d %d", i, j);
    }
    
  • 相关阅读:
    BZOJ1568:[JSOI2008]Blue Mary开公司
    HDU4348:To the moon
    洛谷【P3437】[POI2006]TET-Tetris 3D
    AtCoder Regular Contest 072 E:Alice in linear land
    AtCoder Grand Contest 014 D:Black and White Tree
    洛谷【P2664】树上游戏
    浅谈树分治
    BZOJ3784:树上的路径
    BZOJ2006:[NOI2010]超级钢琴
    BZOJ3648:寝室管理
  • 原文地址:https://www.cnblogs.com/nosae/p/15832832.html
Copyright © 2020-2023  润新知