[AcWing 4480] 倒垃圾

image
image


点击查看代码
#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 2e5 + 10;

int n, m;
int x[N], t[N];
vector<int> a, b, c;

int findl(int x)
{
    int l = 0, r = m - 1;
    while (l < r) {
        int mid = l + r + 1 >> 1;
        if (b[mid] <= x)
            l = mid;
        else
            r = mid - 1;
    }
    return l;
}

int findr(int x)
{
    int l = 0, r = m - 1;
    while (l < r) {
        int mid = l + r >> 1;
        if (b[mid] >= x)
            r = mid;
        else
            l = mid + 1;
    }
    return l;
}

void solve()
{
    cin >> n >> m;
    for (int i = 0; i < n + m; i ++)
        cin >> x[i];
    for (int i = 0; i < n + m; i ++)
        cin >> t[i];
    for (int i = 0; i < n + m; i ++) {
        if (t[i] == 1) {
            b.push_back(x[i]);
            c.push_back(0);
        }
        else
            a.push_back(x[i]);
    }
    for (int i = 0; i < n; i ++) {
        int l = findl(a[i]), r = findr(a[i]);
        if (abs(b[l] - a[i]) <= abs(b[r] - a[i]))
            c[l] ++;
        else
            c[r] ++;
    }
    for (int i = 0; i < m; i ++)
        cout << c[i] << ' ';
    cout << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    solve();

    return 0;
}

  1. \(a\) 数组来记录所有居民住所的坐标,\(b\) 数组来记录所有垃圾桶的坐标
    对于每一个 \(a_i\),用两次二分分别找到满足 \(b_j \leqslant a_i\) 的最大的 \(j\)\(b_k \geqslant a_i\) 的最小的 \(k\),根据题意条件,如果 \(|b_j - a_i| \leqslant |b_k - a_i|\),垃圾应当倒在 \(j\),否则,垃圾应当倒在 \(k\)
posted @ 2022-06-27 14:19  wKingYu  阅读(41)  评论(0)    收藏  举报