AcWing 3874. 三元组的最小距离(2020年408真题)

273 阅读1分钟

解法一

假设 a,b,ca, b, c 分别属于 S1,S2,S3 S1, S2,S3 \ ,并且满足 a<=b<=ca<=b<=c,则可以通过二分找到所有满足这种关系的三元组

时间复杂度 O(klogk)O(klogk) [其中 k=max(l,m,n)k=max(l, m, n) ], 空间复杂度 O(1)O(1)

#include <bits/stdc++.h>
using namespace std;

int l, m, n;
vector<long long> s[3];

long long sol(int i, int j, int k)
{
    long long ans = 1e18, l = s[i].size(), m = s[j].size(), n = s[k].size();
    for(int it = 0; it < m; it ++) {
        int x = s[j][it];
        int p = upper_bound(s[i].begin(), s[i].end(), x) - s[i].begin(); // 小于等于 x
        int q = lower_bound(s[k].begin(), s[k].end(), x) - s[k].begin(); // 大于等于 x
        p --;
        if(p == -1 or q == n) continue;
        ans = min(ans, s[k][q] * 2 - s[i][p] * 2);
    }
    return ans;
}

signed main()
{
    cin >> l >> m >> n;
    s[0].resize(l), s[1].resize(m), s[2].resize(n);
    for(int i = 0; i < l; i ++) cin >> s[0][i];
    for(int i = 0; i < m; i ++) cin >> s[1][i];
    for(int i = 0; i < n; i ++) cin >> s[2][i];
    long long ans = min(sol(0, 1, 2), sol(2, 1, 0));
    ans = min(ans, min(sol(1, 0, 2), sol(2, 0, 1)));
    ans = min(ans, min(sol(0, 2, 1), sol(1, 2, 0)));
    cout << ans << endl;
    return 0;
}

解法二

S1,S2,S3S1, S2, S3 中选择三个数 a,b,ca, b, c,这三个数一定会满足升序的关系,假设 a<=b<=ca<=b<=c,为了使距离之和最小,又因为集合 SS 递增,增大 aa 的值才可能减少距离之和

时间复杂度 O(k)O(k) [其中 k=max(l,m,n)k=max(l, m, n) ], 空间复杂度 O(1)O(1)

#include <bits/stdc++.h>
using namespace std;

int l, m, n;
vector<long long> s[3];

long long sol()
{
    long long ans = 1e18;
    int i = 0, j = 0, k = 0;
    while(i != l and j != m and k != n) {
        long long x = s[0][i], y = s[1][j], z = s[2][k];
        ans = min(ans, abs(y - x) + abs(z - y) + abs(z - x));
        if(x <= y and x <= z) i ++;
        else if(y <= x and y <= z) j ++;
        else k ++;
    }
    return ans;
}

signed main()
{
    cin >> l >> m >> n;
    s[0].resize(l), s[1].resize(m), s[2].resize(n);
    for(int i = 0; i < l; i ++) cin >> s[0][i];
    for(int i = 0; i < m; i ++) cin >> s[1][i];
    for(int i = 0; i < n; i ++) cin >> s[2][i];
    long long ans = sol();
    cout << ans << endl;
    return 0;
}