4480. 倒垃圾 - AcWing题库 用二分更好理解:
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int>PII;
const int N = 1e5;
vector<int>x;
vector<PII>a;
vector<int>b;
//找x左边最靠近 x 的垃圾桶
int find1(int c) {
int l = 0, r = a.size() - 1;
while (l < r) {
int mid = l + r + 1 >> 1;
if (a[mid].first <= c) //如果mid小于x,说明右边还有更靠近x的
l = mid;
else
r = mid - 1; //否则就是走多了,往回走
}
return l;
}
//找x右边最靠近 x 的垃圾桶
int find2(int c) {
int l = 0, r = a.size() - 1;
while (l < r) {
int mid = l + r >> 1;
if (a[mid].first >= c)
r = mid;
else
l = mid + 1;
}
return l;
}
void sovel() {
int n, m;
cin >> n >> m;
//输入居民楼和垃圾桶的坐标
for (int i = 0; i < (n + m); i++) {
int c;
cin >> c;
x.push_back(c);
}
//输入居民楼和垃圾桶的标记
for (int i = 0; i < (n + m); i++) {
//a存垃圾桶的坐标和垃圾桶被使用的次数,b存居民楼的坐标
int c;
cin >> c;
if (c)
a.push_back({x[i], 0});
else
b.push_back(x[i]);
}
for (int i = 0; i < b.size(); i++) {
int c = b[i];
int x1 = find1(c), x2 = find2(c);
if (x1 == x2) { //说明找到的是一个垃圾桶,那就把前面的垃圾桶+1
a[x1].second += 1;
} else {
//看一下哪个坐标距离c更近
if (abs(c - a[x1].first) <= abs(c - a[x2].first))
a[x1].second += 1;
else
a[x2].second += 1;
}
}
//输出结果
for (int i = 0; i < a.size(); i++)
cout << a[i].second << " ";
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int t = 1;
while (t--)
sovel();
return 0;
}