QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#65881 | #4226. Cookie Cutter | Sorting | RE | 1ms | 3464kb | C++ | 5.1kb | 2022-12-04 07:17:03 | 2022-12-04 07:17:06 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 3;
const int M = 3000 + 3;
typedef long long ll;
typedef long double ld;
const ld EPS = 1e-7;
#define all(x) (x).begin(), (x).end()
template<class T>
struct Point {
typedef Point P;
T x, y;
Point(){}
Point(T x, T y): x(x), y(y){}
bool operator==(P p){
return p.x == x && p.y == y;
}
T dist2() const{
return x * x + y * y;
}
ld dist() const {
return sqrt(x * x + y * y);
}
P operator*(T coeff){
return {x * coeff, y * coeff};
}
P operator/(T coeff){
return {x / coeff, y / coeff};
}
P operator+(P p){
return {x + p.x, y + p.y};
}
P operator-(P p){
return {x - p.x, y - p.y};
}
T cross(P p){
return x * p.y - y * p.x;
}
T cross(P a, P b){
return (*this - a).cross(*this - b);
}
T dot(P p) const {
return x * p.x + y * p.y;
}
friend bool operator<(const Point &l, const Point &r){
return tuple{l.x, l.y} < tuple{r.x, r.y};
}
};
struct Angle{
ld x, y, t;
Angle(ld x, ld y): x(x), y(y){}
int half() const{
assert(x || y);
return y < 0 || (y == 0 && x < 0);
}
};
bool operator<(Angle a, Angle b){
return make_tuple(a.t, a.half(), a.y*(ll)b.x) <
make_tuple(b.t, b.half(), a.x*(ll)b.y);
}
int n, m;
Point<ll> p[M];
template<class P>
pair<int, P> lineInter(P s1, P e1, P s2, P e2){
auto d = (e1 - s1).cross(e2 - s2);
if(d == 0)
return pair{-(s1.cross(e1, s2) == 0), P{(ld)0, (ld)0}};
auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
return {1, (s1 * p + e1 * q) / d};
}
ld segDist(Point<ld> &s, Point<ld> &e, Point<ld> &p){
if(s == e) return (p - s).dist();
ld d = (s - e).dist2();
ld t = min(d, max((ld).0, (p - s).dot(e-s)));
return ((p-s)*d-(e-s)*t).dist()/d;
}
template<class T>
T polygonArea2(vector<Point<T>> &v){
T a = v.back().cross(v[0]);
for(int i = 0; i < (int)v.size() - 1; ++i)
a += v[i].cross(v[i + 1]);
return a;
}
ld area_right(Point<ld> a, Point<ld> b){
// cout << a.x << " " << a.y << " - " << b.x << " " << b.y << endl;
vector<Point<ld>> corners{{0, 0}, {0, n}, {n, n}, {n, 0}};
vector<Point<ld>> points;
for(int i = 0; i < 4; ++i){
int nxt = (i + 1) % 4;
auto inters = lineInter(a, b, corners[i], corners[nxt]);
if(!inters.first)
continue;
if(segDist(corners[i], corners[nxt], inters.second) <= EPS)
points.push_back(inters.second);
}
for(int i = 0; i < 4; ++i)
points.push_back(corners[i]);
vector<Point<ld>> points2;
for(auto p: points)
if(a.cross(b, p) >= 0)
points2.push_back(p);
sort(all(points2));
points2.resize(unique(all(points2)) - points2.begin());
vector<Angle> v;
for(auto p: points2){
auto dp = p - points2[0];
if(dp.dist() > EPS)
v.push_back(Angle(dp.x, dp.y));
}
sort(all(v));
vector<Point<ld>> points3;
points3.push_back(points2[0]);
for(auto ang: v){
points3.push_back(Point<ld>{ang.x + points2[0].x, ang.y + points2[0].y});
}
// cout << "points3: " << endl;
// for(auto [x, y]: points3)
// cout << x << " " << y << endl;
// cout << endl;
// cout << polygonArea2(points3) / 2 << " wtf guys" << endl;
return abs(polygonArea2(points3)) / 2;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m;
for(int i = 0; i < m; ++i)
cin >> p[i].x >> p[i].y;
ld ans = 0;
for(int i = 0; i < m; ++i){
// cout << i << " i" << endl;
vector<Point<ld>> corners{{0, 0}, {0, n}, {n, n}, {n, 0}};
for(auto corner: corners){
ans = max(ans, (ld)1/m - area_right(Point<ld>{p[i].x, p[i].y}, corner) / (ld)(n * n));
ans = max(ans, (ld)1/m - area_right(corner, Point<ld>{p[i].x, p[i].y}) / (ld)(n * n));
}
}
// cout << ans << " ans" << endl;
for(int i = 0; i < n; ++i){
vector<Angle> v;
for(int j = 0; j < n; ++j){
if(i == j) continue;
v.push_back(Angle(p[j].x - p[i].x, p[j].y - p[i].y));
}
sort(all(v));
int j = 0, ptr = 0;
for(; j < n - 1; ++j){
// cout << i << " " << j << " " << ptr << endl;
while((ptr + 1) % (n - 1) != j && Point<ld>{(ld)0,(ld)0}.cross(Point<ld>{v[j].x, v[j].y}, Point<ld>{v[(ptr + 1) % (n - 1)].x, v[(ptr + 1) % (n - 1)].y}) >= 0){
++ptr;
ptr %= n - 1;
}
int cnt = ptr - j + 1;
if(cnt <= 0)
cnt += n - 1;
ans = max(ans, (long double)(cnt + 1) / (long double)m - area_right(Point<ld>{p[i].x, p[i].y}, Point<ld>{v[j].x + p[i].x, v[j].y + p[i].y}) / (ld)((ld)n * n));
if(ptr == j)
++ptr;
}
}
cout << fixed << setprecision(12) << ans << "\n";
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3464kb
input:
5 8 1 1 1 2 1 3 2 1 3 1 3 4 4 1 4 2
output:
0.375000000000
result:
ok found '0.3750000', expected '0.3750000', error '0.0000000'
Test #2:
score: -100
Runtime Error
input:
10000 2916 93 93 93 278 93 463 93 649 93 834 93 1019 93 1204 93 1389 93 1574 93 1760 93 1945 93 2130 93 2315 93 2500 93 2685 93 2871 93 3056 93 3241 93 3426 93 3611 93 3796 93 3982 93 4167 93 4352 93 4537 93 4722 93 4907 93 5093 93 5278 93 5463 93 5648 93 5833 93 6018 93 6204 93 6389 93 6574 93 6759...