QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#87783 | #5570. Epidemic Escape | applese | WA | 3ms | 6120kb | C++14 | 6.6kb | 2023-03-14 10:14:53 | 2023-03-14 10:14:56 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
const double eps = 1e-8;
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 = 2e4;
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: %.15Lf 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])))
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])))
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])))
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])))
dismax[i] = x;
}
// for(int j = 0; j < sz[i]; ++ j) {
// if(Dcmp(Dis(now, nowp, hull[i][dismax[i]]) < Dis(now, nowp, hull[i][j])))
// 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 << 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)
puts("-1");
else
// printf("%lld\n", (long long)round(invr * invr / ans / 2 * 1e7));
printf("%.15f\n", invr * invr / ans / 2);
}
}
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 6048kb
input:
5 5 -3 5 4 -6 2 -5 0 4 1 2 -3 -10 1 6 -9 1
output:
8.700255424092052 3.226019562257246
result:
ok 2 numbers
Test #2:
score: 0
Accepted
time: 1ms
memory: 5984kb
input:
8 4 -1 4 -8 0 9 4 -7 -5 -2 5 -5 7 5 -9 2 10 4 -8 1 7 -7 5 -10 8 2 -9 9 2 4 -7 5 -1 -10 2 6 -3 2 2 -9 3 -10 -10 1 5 9 1
output:
3.167762968124700 26.162950903902797 5.461488320163356 6.363961030678952 -1 5.289408221642564 3.726779962499644 4.609772228646474 2.929442379201408 4.761728940206468
result:
ok 10 numbers
Test #3:
score: -100
Wrong Answer
time: 0ms
memory: 6120kb
input:
5 -4 -7 5 0 2 4 -7 -7 4 4 20 0 -5 2 -4 -7 2 -7 7 3 4 -4 3 -7 4 3 4 -4 1 2 4 1 6 -7 2 4 -4 2 4 4 3 5 4 1 -1 9 2 8 9 3 4 -4 2 6 3 3 -10 -3 2 -7 7 1 9 -4 1 -4 -7 3 -2 0 2
output:
7.000000000000008 5.130527658008234 -1 838860800000000.000000000000000 -1 3.535533905932721 2.236067977499784 11.985407794480672 15.320646925707983 3.535533905932721 2.462740091320331 4.527692569068690 3.762998305872593 15.320646925707983 2.981423969999723 5.621703504797920 7.071067811865501 2.73579...
result:
wrong answer 4th numbers differ - expected: '-1.0000000', found: '838860800000000.0000000', error = '838860800000001.0000000'