标签:ace empty str top print ++ set scan amp
题目等价于一些点在平面上,一个机器人可以取走做平面或下平面的所有点,一轮一个机器人只能取一次。求最少多少次才能把所有点都取走。
先二分多少次可以把所有点都去走。那么每个机器人取的次数 \(\le m\) 。考虑贪心。将所有点用 \(x\) 轴排序,从可取得范围小到可取得范围大考虑所有可以取左平面的机器人。对于每个机器人,很明显先取\(y\) 坐标大得机器人。再考虑所有取下平面得机器人即可。
那么需要做以下几件事情:
这次注意开 long long 了。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
const int CT = 1e6 + 5, CAB = 5e4 + 5;
int a, b, t, X[CAB], Y[CAB];
struct Toy {
int w, s;
Toy(int _w = 0, int _s = 0) : w(_w), s(_s) {}
} toy[CT];
bool cmp(const Toy &x, const Toy &y) { return x.w < y.w; }
struct cmp1 {
bool operator()(const Toy &x, const Toy &y) { return x.s < y.s; }
//如果函数返回值是 1,那么 y在上面
};
priority_queue<Toy, vector<Toy>, cmp1> H1;
int que[CT];
bool check(int ans) {
while (!H1.empty()) H1.pop();
int pt = 1;
for (int i = 1; i <= a; ++i) {
while (pt <= t && toy[pt].w < X[i]) {
H1.push(toy[pt]);
++pt;
}
for (int j = 1; j <= ans; ++j) {
if (H1.empty()) break ; //这个地方开始写成了 !H1.empty()
H1.pop();
}
}
//还可能有一些根本没有被塞进去的点(就是没有一个x[i]的机器人能消灭他),这里得加上
for (int i = pt; i <= t; ++i)
H1.push(toy[i]);
int tail = 0;
while (!H1.empty()) {
que[++tail] = H1.top().s;
H1.pop();
}
sort(que + 1, que + tail + 1);
pt = 1;
for (int i = 1; i <= b; ++i) {
int cnt = 0;
while (pt <= tail && que[pt] < Y[i] && cnt < ans) {
++cnt;
++pt;
}
}
if (pt == tail + 1) return 1;
else return 0;
}
int main() {
scanf("%d%d%d", &a, &b, &t);
for (int i = 1; i <= a; ++i) scanf("%d", &X[i]);
for (int i = 1; i <= b; ++i) scanf("%d", &Y[i]);
sort(X + 1, X + a + 1);
sort(Y + 1, Y + b + 1);
for (int i = 1; i <= t; ++i) {
scanf("%d%d", &toy[i].w, &toy[i].s);
if (X[a] <= toy[i].w && Y[b] <= toy[i].s) {
printf("-1\n");
return 0;
}
}
sort(toy + 1, toy + t + 1, cmp);
int L = 1, R = 1e6, ans;
while (L <= R) {
int mid = (L + R) >> 1;
if (check(mid)) {
ans = mid;
R = mid - 1;
} else
L = mid + 1;
}
printf("%d\n", ans);
return 0;
}
【题解】【LuoguP5894】【IOI2013】robots
标签:ace empty str top print ++ set scan amp
原文地址:https://www.cnblogs.com/YouthRhythms/p/13363830.html