QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#87790 | #5570. Epidemic Escape | applese | RE | 0ms | 0kb | C++14 | 6.9kb | 2023-03-14 10:36:48 | 2023-03-14 10:36:49 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
const double eps = 1e-9;
int Dcmp(double x) {
return x < -eps ? -1 : x > eps ? 1 : 0;
}
struct Point {
double x, y;
int id;
Point(double x = 0, double y = 0, int id = 0) : x(x), y(y), id(id) {}
Point operator == (const Point &rhs) const {
return Dcmp(x - rhs.x) == 0 && Dcmp(y - rhs.y) == 0;
}
Point operator + (const Point &rhs) const {
return Point(x + rhs.x, y + rhs.y);
}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
Point operator * (const double &k) const {
return Point(x * k, y * k);
}
Point operator / (const double &k) const {
return Point(x / k, y / k);
}
double operator * (const Point &rhs) const {
return x * rhs.x + y * rhs.y;
}
double operator ^ (const Point &rhs) const {
return x * rhs.y - y * rhs.x;
}
double len2() {
return x * x + y * y;
}
double len() {
return sqrt(len2());
}
Point Unit() {
return *this / len();
}
}p[maxn];
double invr = 5e3;
int n, cntp, tot, vis[maxn], q, sz[6], dismax[6], cnt[6];
vector<Point> hull[6], now;
int Left(Point a, Point b, Point c) { // b is left of ac
return Dcmp((b - a) ^ (c - a)) >= 0;
}
Point base;
vector<Point> Convex(vector<Point> a) {
int n = a.size(), cnt = 0;
if(n < 3)
return a;
for(auto p : a)
if(make_pair(p.x, p.y) < make_pair(base.x, base.y))
base = p;
sort(a.begin(), a.end(), [](const Point &a, const Point &b) {
int d = Dcmp((a - base) ^ (b - base));
if(d)
return d > 0;
return Dcmp((a - base).len2() - (b - base).len2()) < 0;
});
vector<Point> res;
for(int i = 0; i < n; ++ i) {
while(cnt > 1 && Left(res[cnt - 2], a[i], res[cnt - 1]))
-- cnt, res.pop_back();
res.push_back(a[i]), ++ cnt;
}
int fixed = cnt;
for(int i = n - 2; ~i; -- i) {
while(cnt > fixed && Left(res[cnt - 2], a[i], res[cnt - 1]))
-- cnt, res.pop_back();
res.push_back(a[i]), ++ cnt;
}
res.pop_back();
return res;
}
double Dis(Point s, Point t, Point p) {
Point v1 = t - s, v2 = p - s;
return (v2 ^ v1) / v1.len();
}
int lp[6], rp[6];
struct Node {
double dd;
int hullid, id;
Node(double dd = 0, int hullid = 0, int id = 0) : dd(dd), hullid(hullid), id(id) {}
bool operator < (const Node &rhs) const {
int d = Dcmp(dd - rhs.dd);
return d ? d < 0 : hullid == rhs.hullid ? id < rhs.id : hullid < rhs.hullid;
}
};
priority_queue<Node>que;
vector<Point> lower[6], upper[6];
pair<double, int> Get(vector<Point> con, Point p) {
int l = 0, r = (int)con.size() - 2;
for(; l + 1 < r; ) {
int mid = (l + r) / 2;
if(Dcmp((con[mid + 1] - con[mid]) ^ p) > 0)
r = mid;
else
l = mid;
}
return max(make_pair(p ^ con[r], r), make_pair(p ^ con[0], 0));
}
int Gett(int id, Point v) {
auto ret = Get(upper[id], v);
ret.second = (ret.second + (int)lower[id].size() - 1) % sz[id];
ret = max(ret, Get(lower[id], v));
return ret.second;
}
int main() {
scanf("%d", &n);
for(int i = 1, x, y; i <= n; ++ i) {
scanf("%d%d", &x, &y);
if(x == 0 && y == 0) {
++ cntp;
}
else {
Point w = Point(x, y, i);
Point v = w.Unit();
double nowl = w.len();
double newl = invr * invr / nowl;
p[++ tot] = v * newl;
p[tot].id = tot;
}
}
for(int k = 0; k < 5; ++ k) {
now.clear();
for(int i = 1; i <= tot; ++ i) {
if(!vis[i]) {
now.push_back(p[i]);
}
}
hull[k] = Convex(now);
sz[k] = hull[k].size();
if(sz[k]) {
// cerr << "Hull " << k << ": " << endl;
for(auto w : hull[k]) {
vis[w.id] = 1;
// cerr << "(" << w.x << ", " << w.y << ") Id = " << w.id << endl;
}
int pos = 0;
for(int i = 0; i < sz[k]; ++ i) {
if(Dcmp(hull[k][i].x - hull[k][pos].x) > 0) {
pos = i;
}
}
// cerr << pos << endl;
for(int i = 0; i <= pos; ++ i) {
lower[k].push_back(hull[k][i]);
}
for(int i = pos; i < sz[k]; ++ i) {
upper[k].push_back(hull[k][i]);
}
upper[k].push_back(hull[k][0]);
}
// cerr << sz[k] << endl;
}
scanf("%d", &q);
for(int x, y, k; q --; ) {
scanf("%d%d%d", &x, &y, &k);
if(!x && !y) {
puts("-1");
continue;
}
if(k <= cntp) {
puts("0");
continue;
}
k -= cntp;
while(!que.empty())
que.pop();
double newl = invr * invr * 4;
Point dir = Point(-y, x), v = Point(x, y).Unit();
Point now = v * newl, nowp = now + dir; // now + dir
for(int i = 0; i < 5; ++ i) {
if(!sz[i])
continue;
// fprintf(stderr, "Hull %d: \n", i);
// for(auto w : hull[i])
// fprintf(stderr, "Dis: %.15f Id: %d\n", Dis(now, nowp, w), w.id);
dismax[i] = cnt[i] = 0;
if(sz[i] > 1) {
int pos1 = Gett(i, dir), pos2 = Gett(i, Point(-dir.x, -dir.y));
dismax[i] = pos1;
for(int C = 0, x = pos2; C <= 2; ++ C, x = (x + 1) % sz[i]) {
if(Dcmp(Dis(now, nowp, hull[i][dismax[i]]) - Dis(now, nowp, hull[i][x])) < 0)
dismax[i] = x;
}
for(int C = 0, x = pos1; C <= 2; ++ C, x = (x + 1) % sz[i]) {
if(Dcmp(Dis(now, nowp, hull[i][dismax[i]]) - Dis(now, nowp, hull[i][x])) < 0)
dismax[i] = x;
}
for(int C = 0, x = pos2; C <= 2; ++ C, x = (x + sz[i] - 1) % sz[i]) {
if(Dcmp(Dis(now, nowp, hull[i][dismax[i]]) - Dis(now, nowp, hull[i][x])) < 0)
dismax[i] = x;
}
for(int C = 0, x = pos1; C <= 2; ++ C, x = (x + sz[i] - 1) % sz[i]) {
if(Dcmp(Dis(now, nowp, hull[i][dismax[i]]) - Dis(now, nowp, hull[i][x])) < 0)
dismax[i] = x;
}
for(int j = 0; j < sz[i]; ++ j) {
int d = Dcmp(Dis(now, nowp, hull[i][dismax[i]]) - Dis(now, nowp, hull[i][j]));
if(d < 0) {
assert(0);
}
}
// for(int j = 0; j < sz[i]; ++ j) {
// if(Dcmp(Dis(now, nowp, hull[i][dismax[i]]) - Dis(now, nowp, hull[i][j])) < 0)
// dismax[i] = j;
// }
}
// cerr << dismax[i] << endl;
lp[i] = rp[i] = dismax[i];
que.push(Node(Dis(now, nowp, hull[i][dismax[i]]), i, dismax[i]));
}
double ans = 1e18;
for(int c = 1; c <= k; ++ c) {
Node w = que.top();
que.pop();
// cerr << w.dd << " " << w.hullid << " " << w.id << " " << w.dd + newl << endl;
if(Dcmp(w.dd + newl) <= 0)
break;
if(c == k) {
ans = newl + w.dd;
break;
}
int i = w.hullid, pos = w.id;
++ cnt[i];
if(cnt[i] == sz[i])
continue;
if(lp[i] == pos) {
-- lp[i];
if(lp[i] < 0)
lp[i] += sz[i];
if(lp[i] != rp[i]) {
que.push(Node(Dis(now, nowp, hull[i][lp[i]]), i, lp[i]));
}
}
if(rp[i] == pos) {
++ rp[i];
if(rp[i] >= sz[i])
rp[i] -= sz[i];
if(lp[i] != rp[i]) {
que.push(Node(Dis(now, nowp, hull[i][rp[i]]), i, rp[i]));
}
}
}
// cerr << ans << endl;
if(ans > 1e16 || Dcmp(ans) <= 0 || Dcmp(invr * invr / ans / 2 - 1e9) > 0)
puts("-1");
else
// printf("%lld\n", (long long)round(invr * invr / ans / 2 * 1e7));
printf("%.15f\n", invr * invr / ans / 2);
}
}
詳細信息
Test #1:
score: 0
Dangerous Syscalls
input:
5 5 -3 5 4 -6 2 -5 0 4 1 2 -3 -10 1 6 -9 1