QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#87790#5570. Epidemic EscapeappleseRE 0ms0kbC++146.9kb2023-03-14 10:36:482023-03-14 10:36:49

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-03-14 10:36:49]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2023-03-14 10:36:48]
  • 提交

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

output:


result: