我一向是不怎么在这里放Coding相关的东西的(包含算法竞赛和信息安全竞赛)。
可是本懒虫渐渐地就失去了在博客写日常的动力;功利点说以后找工作的时候放个除了黑历史什么都看不到的博客也不太好…… 以后也稍微把OneNote / StickyNotes上的东西放到这里来吧。
というわけで。
以加速度为第一关键字升序,以初始位置为第二关键字升序排序。重复元素保留一个并打上标记。复杂度O(n log n)。
从左至右遍历所有元素。将当前元素记为e,栈顶的两个元素(如果存在)分别记为t1和t2。如果e的初始位置不比t1低,那么e总是会在t1的上方,t1出栈;如果t1追赶t2所需的时间比e追赶t1所需的时间还少,那么t1也出栈。对于每个元素总是进行这样的检查,直到不再有元素出栈为止,复杂度O(n)。
WA点:本垃圾时隔数月又忘记long long了。>=漏个=什么的也……
/* HDU 2020 - Training 1
* Problem I
* Au: SJoshua
*/
#include <bits/stdc++.h>
#ifndef open_dbg_func
#define dbg(...) (__VA_ARGS__)
#endif
using namespace std;
struct Robot {
long long p, a;
bool dup;
bool operator < (const Robot &r) const {
return a == r.a ? p < r.p : a < r.a;
}
bool operator == (const Robot &r) const {
return p == r.p && a == r.a;
}
friend ostream& operator << (ostream &stream, const Robot &r) {
return stream << "(a = " << r.a << ", p = " << r.p << ", dup = " << (r.dup ? "true" : "false") << ")";
}
};
bool judge(Robot &a, Robot &b, Robot &c) {
return (b.p - c.p) * (b.a - a.a) - (a.p - b.p) * (c.a - b.a) <= 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector <Robot> robots(n);
for (int i = 0; i < n; i++) {
cin >> robots[i].p >> robots[i].a;
}
sort(robots.begin(), robots.end());
for (int i = 1; i < n; i++) {
if (robots[i - 1] == robots[i]) {
robots[i - 1].dup = robots[i].dup = true;
}
}
robots.resize(unique(robots.begin(), robots.end()) - robots.begin());
vector <Robot> stack;
for (auto e: robots) {
while ((!stack.empty() && e.p >= stack.back().p) || (stack.size() > 1 && judge(stack[stack.size() - 2], stack[stack.size() - 1], e))) {
stack.pop_back();
}
stack.push_back(e);
}
int ans = 0;
for (auto e: stack) {
ans += !e.dup;
}
cout << ans << endl;
}
return 0;
}
