QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#729138 | #9576. Ordainer of Inexorable Judgment | ucup-team133# | WA | 0ms | 3916kb | C++23 | 10.3kb | 2024-11-09 16:33:05 | 2024-11-09 16:33:06 |
Judging History
你现在查看的是最新测评结果
- [2024-12-23 14:23:26]
- hack成功,自动添加数据
- (/hack/1303)
- [2024-12-06 11:32:56]
- hack成功,自动添加数据
- (/hack/1271)
- [2024-11-14 21:58:28]
- hack成功,自动添加数据
- (/hack/1181)
- [2024-11-09 16:33:05]
- 提交
answer
#include <bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...) void(0)
#endif
template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) {
for (auto& e : v) {
is >> e;
}
return is;
}
template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
for (std::string_view sep = ""; const auto& e : v) {
os << std::exchange(sep, " ") << e;
}
return os;
}
template <class T, class U = T> bool chmin(T& x, U&& y) {
return y < x and (x = std::forward<U>(y), true);
}
template <class T, class U = T> bool chmax(T& x, U&& y) {
return x < y and (x = std::forward<U>(y), true);
}
template <class T> void mkuni(std::vector<T>& v) {
std::ranges::sort(v);
auto result = std::ranges::unique(v);
v.erase(result.begin(), result.end());
}
template <class T> int lwb(const std::vector<T>& v, const T& x) {
return std::distance(v.begin(), std::ranges::lower_bound(v, x));
}
#include <type_traits>
namespace geometry {
template <typename T> struct Point {
static T EPS;
static void set_eps(T eps) { EPS = eps; }
T x, y;
Point() {}
Point(T x, T y) : x(x), y(y) {}
Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
Point operator*(T t) const { return Point(x * t, y * t); }
Point operator/(T t) const { return Point(x / t, y / t); }
bool operator==(const Point& p) const { return x == p.x and y == p.y; }
bool operator!=(const Point& p) const { return not((*this) == p); }
bool operator<(const Point& p) const { return x != p.x ? x < p.x : y < p.y; }
friend std::istream& operator>>(std::istream& is, Point& p) { return is >> p.x >> p.y; }
friend std::ostream& operator<<(std::ostream& os, const Point& p) { return os << p.x << ' ' << p.y; }
T norm() { return std::sqrt(x * x + y * y); }
T norm2() { return x * x + y * y; }
T arg() { return std::atan2(y, x); }
T dot(const Point& p) { return x * p.x + y * p.y; }
T det(const Point& p) { return x * p.y - y * p.x; }
Point perp() { return Point(-y, x); }
Point unit() { return *this / norm(); }
Point normal() { return perp().unit(); }
Point rotate(T rad) { return Point(std::cos(rad) * x - std::sin(rad) * y, std::sin(rad) * x + std::cos(rad) * y); }
};
template <> double Point<double>::EPS = 1e-9;
template <> long double Point<long double>::EPS = 1e-12;
template <> int Point<int>::EPS = 0;
template <> long long Point<long long>::EPS = 0;
template <typename T> int sgn(T x) { return x < -Point<T>::EPS ? -1 : x > Point<T>::EPS ? 1 : 0; }
} // namespace geometry
namespace geometry {
enum Position { COUNTER_CLOCKWISE = +1, CLOCKWISE = -1, ONLINE_BACK = +2, ONLINE_FRONT = -2, ON_SEGMENT = 0 };
template <typename T> Position ccw(const Point<T>& a, Point<T> b, Point<T> c) {
b = b - a;
c = c - a;
if (sgn(b.det(c)) == 1) return COUNTER_CLOCKWISE;
if (sgn(b.det(c)) == -1) return CLOCKWISE;
if (sgn(b.dot(c)) == -1) return ONLINE_BACK;
if (b.norm2() < c.norm2()) return ONLINE_FRONT;
return ON_SEGMENT;
}
} // namespace geometry
namespace geometry {
template <typename T> struct Polygon : std::vector<Point<T>> {
using std::vector<Point<T>>::vector;
Polygon(int n) : std::vector<Point<T>>(n) {}
T area2() {
T sum = 0;
int n = this->size();
for (int i = 0; i < n; i++) sum += (*this)[i].det((*this)[i + 1 == n ? 0 : i + 1]);
return sum < 0 ? -sum : sum;
}
T area() { return area2() / 2; }
bool is_convex() {
int n = this->size();
for (int j = 0; j < n; j++) {
int i = (j == 0 ? n - 1 : j - 1), k = (j == n - 1 ? 0 : j + 1);
if (ccw((*this)[i], (*this)[j], (*this)[k]) == CLOCKWISE) return false;
}
return true;
}
};
} // namespace geometry
namespace geometry {
template <typename T> struct Circle {
Point<T> c;
T r;
Circle() {}
Circle(Point<T> c, T r) : c(c), r(r) {}
friend std::istream& operator>>(std::istream& is, Circle& c) { return is >> c.c >> c.r; }
friend std::ostream& operator<<(std::ostream& os, const Circle& c) { return os << c.c << ' ' << c.r; }
};
} // namespace geometry
namespace geometry {
template <typename T> struct Line {
Point<T> a, b;
Line() {}
Line(const Point<T>& a, const Point<T>& b) : a(a), b(b) {}
// A * x + B * y + C = 0
Line(T A, T B, T C) {}
friend std::istream& operator>>(std::istream& is, Line& l) { return is >> l.a >> l.b; }
friend std::ostream& operator<<(std::ostream& os, const Line& l) { return os << l.a << " to " << l.b; }
};
template <typename T> struct Segment : Line<T> {
Segment() {}
Segment(const Point<T>& a, const Point<T>& b) : Line<T>(a, b) {}
};
} // namespace geometry
namespace geometry {
template <typename T> Point<T> projection(const Line<T>& l, const Point<T>& p) {
Point<T> a = p - l.a, b = l.b - l.a;
return l.a + b * a.dot(b) / b.norm2();
}
} // namespace geometry
namespace geometry {
template <typename T> bool is_parallel(const Line<T>& l, const Line<T>& m) {
return sgn((l.b - l.a).det(m.b - m.a)) == 0;
}
template <typename T> bool is_orthogonal(const Line<T>& l, const Line<T>& m) {
return sgn((l.b - l.a).dot(m.b - m.a)) == 0;
}
template <typename T> bool has_crosspoint(const Segment<T>& s, const Segment<T>& t) {
return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 and ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
template <typename T> int count_common_tangent(const Circle<T>& c, const Circle<T>& d) {
T dist = (c.c - d.c).norm();
int tmp = sgn(dist - (c.r + d.r));
if (tmp > 0) return 4;
if (tmp == 0) return 3;
tmp = sgn(dist - (sgn(c.r - d.r) > 0 ? c.r - d.r : d.r - c.r));
if (tmp > 0) return 2;
if (tmp == 0) return 1;
return 0;
}
template <typename T> Point<T> crosspoint(const Line<T>& l, const Line<T>& m) {
assert(not is_parallel(l, m));
Point<T> u = l.b - l.a, v = m.b - m.a;
return l.a + u * v.det(m.a - l.a) / v.det(u);
}
template <typename T> Point<T> crosspoint(const Segment<T>& s, const Segment<T>& t) {
assert(has_crosspoint(s, t));
if (not is_parallel(s, t)) return crosspoint(Line(s.a, s.b), Line(t.a, t.b));
std::vector<Point<T>> v = {s.a, s.b, t.a, t.b};
for (int i = 0; i <= 2; i++) {
for (int j = 2; j >= i; j--) {
if (v[j + 1] < v[j]) {
std::swap(v[j], v[j + 1]);
}
}
}
return v[1];
}
template <typename T> std::vector<Point<T>> crosspoint(const Circle<T>& c, const Line<T>& l) {
Point<T> h = projection(l, c.c);
T x = c.r * c.r - (c.c - h).norm2();
if (sgn(x) < 0) return {};
if (sgn(x) == 0) return {h};
Point<T> v = (l.b - l.a).unit() * std::sqrt(x);
return {h - v, h + v};
}
template <typename T> std::vector<Point<T>> crosspoint(const Circle<T>& c, const Segment<T>& s) {}
template <typename T> std::vector<Point<T>> crosspoint(const Circle<T>& c1, const Circle<T>& c2) {
T r1 = c1.r, r2 = c2.r;
if (r1 < r2) return crosspoint(c2, c1);
T d = (c2.c - c1.c).norm();
if (sgn(d - (r1 + r2)) > 0 or sgn(d - (r1 - r2)) < 0) return {};
Point<T> v = c2.c - c1.c;
if (sgn(d - (r1 + r2)) == 0 or sgn(d - (r1 - r2)) == 0) return {c1.c + v.unit() * r1};
T p = ((r1 * r1 - r2 * r2) / d + d) / 2, q = std::sqrt(r1 * r1 - p * p);
Point<T> h = c1.c + v.unit() * p;
Point<T> i = v.normal();
return {h + i * q, h - i * q};
}
} // namespace geometry
namespace geometry {
template <typename T> std::vector<int> sort_points_by_argument(const std::vector<Point<T>>& P) {
auto type = [](const Point<T>& p) {
if (p.x == 0 and p.y == 0) return 0;
return (p.y < 0 or (p.y == 0 and p.x > 0)) ? -1 : 1;
};
int n = P.size();
std::vector<int> res(n);
std::iota(begin(res), end(res), 0);
std::sort(begin(res), end(res), [&](int l, int r) {
int L = type(P[l]), R = type(P[r]);
return L != R ? L < R : P[l].x * P[r].y > P[l].y * P[r].x;
});
return res;
}
template <typename T> std::vector<int> sort_points_by_argument(const std::vector<std::pair<T, T>>& P) {
std::vector<Point<T>> tmp;
for (const auto& [x, y] : P) tmp.emplace_back(x, y);
return sort_points_by_argument(tmp);
}
} // namespace geometry
using namespace std;
using ll = long long;
using namespace geometry;
const long double PI = acosl(-1);
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(15);
int n;
cin >> n;
Point<long double> init;
cin >> init;
int d;
long double t;
cin >> d >> t;
Polygon<long double> P(n);
cin >> P;
vector<Point<long double>> cand;
for (int i = 0; i < n; i++) {
{
long double e = sqrtl(P[i].norm2() - d * d);
auto cs = crosspoint(Circle(Point<long double>(0, 0), e), Circle<long double>(P[i], d));
for (auto p : cs) cand.emplace_back(p);
}
{
auto dir = (P[(i + 1) % n] - P[i]).normal() * d;
cand.emplace_back(P[i] + dir);
cand.emplace_back(P[i] - dir);
cand.emplace_back(P[(i + 1) % n] + dir);
cand.emplace_back(P[(i + 1) % n] - dir);
}
}
auto ord = sort_points_by_argument(cand);
int len = ord.size();
int s = 0;
for (int i = 0; i + 1 < len; i++) {
auto l = cand[ord[i]].arg(), r = cand[ord[i + 1]].arg();
if (r - l >= PI) s = i + 1;
}
rotate(ord.begin(), ord.begin() + s, ord.end());
long double ans = 0;
{
auto cycle = cand[ord.back()].arg() - cand[ord.front()].arg();
if (cycle < 0) cycle += 2 * PI;
int lb = 0, ub = 1e5;
while (ub - lb > 1) {
int mid = (lb + ub) >> 1;
(2 * PI * mid <= t ? lb : ub) = mid;
}
ans += cycle * lb;
t -= 2 * PI * lb;
}
auto L = init.arg(), R = L + t;
if (sgn(L) == -1) {
L += 2 * PI;
R += 2 * PI;
}
for (int i = 0; i + 1 < len; i++) {
auto l = cand[ord[i]].arg(), r = cand[ord[i + 1]].arg();
if (r < l) r += 2 * PI;
if (sgn(l) == -1) {
l += 2 * PI;
r += 2 * PI;
}
ans += max((long double)0, min(r, R) - max(l, L));
}
cout << ans << "\n";
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3908kb
input:
3 1 0 1 1 1 2 2 1 2 2
output:
1.000000000000000
result:
ok found '1.0000000', expected '1.0000000', error '0.0000000'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3904kb
input:
3 1 0 1 2 1 2 2 1 2 2
output:
1.570796326794897
result:
ok found '1.5707963', expected '1.5707963', error '0.0000000'
Test #3:
score: 0
Accepted
time: 0ms
memory: 3908kb
input:
3 1 0 1 10000 1 2 2 1 2 2
output:
2500.707752257475418
result:
ok found '2500.7077523', expected '2500.7077523', error '0.0000000'
Test #4:
score: 0
Accepted
time: 0ms
memory: 3836kb
input:
3 10000 10000 1 10000 10000 9999 10000 10000 9999 10000
output:
0.384241300289662
result:
ok found '0.3842413', expected '0.3842413', error '0.0000000'
Test #5:
score: 0
Accepted
time: 0ms
memory: 3892kb
input:
3 -10000 -10000 10000 10000 -10000 -9999 -10000 -10000 -9999 -10000
output:
2500.240670009608470
result:
ok found '2500.2406700', expected '2500.2406700', error '0.0000000'
Test #6:
score: 0
Accepted
time: 0ms
memory: 3916kb
input:
4 1 0 1 10000 -2 3400 -4 10000 -4 -10000 -2 -3400
output:
4999.219115408742769
result:
ok found '4999.2191154', expected '4999.2191154', error '0.0000000'
Test #7:
score: 0
Accepted
time: 0ms
memory: 3844kb
input:
4 1 0 1 10000 -2 3300 -4 10000 -4 -10000 -2 -3300
output:
4999.200391854815009
result:
ok found '4999.2003919', expected '4999.2003919', error '0.0000000'
Test #8:
score: 0
Accepted
time: 0ms
memory: 3916kb
input:
4 -3040 2716 2147 2 -9033 -8520 -8999 -8533 -8988 -8511 -9004 -8495
output:
0.350830058342073
result:
ok found '0.3508301', expected '0.3508301', error '0.0000000'
Test #9:
score: -100
Wrong Answer
time: 0ms
memory: 3916kb
input:
3 8168 -766 1549 1256 -3951 -6425 -3874 -6439 -3911 -6389
output:
84.408696855201919
result:
wrong answer 1st numbers differ - expected: '84.8328612', found: '84.4086969', error = '0.0050000'