QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#497363#7734. Intersection over UnionlonelywolfTL 0ms3796kbC++234.7kb2024-07-29 02:54:492024-07-29 02:54:50

Judging History

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

  • [2024-07-29 02:54:50]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3796kb
  • [2024-07-29 02:54:49]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double LD;
typedef pair <int, int> pii;

mt19937 eng(time(0));


#define cp const point &
const LD eps = 0;
int sgn (LD x) { return x > eps ? 1 : (x < -eps ? -1 : 0); }
LD sqr (LD x) { return x * x; }
struct point {
    LD x, y;
    point () {}
    point (LD xx, LD yy) { x = xx, y = yy; }
    point operator + (cp a) const { return {x + a.x, y + a.y}; }
    point operator - (cp a) const { return {x - a.x, y - a.y}; }
    point operator * (LD a) const { return {x * a, y * a}; }
    point operator / (LD a) const { return {x / a, y / a}; }
    point rot90() const { return {-y, x}; }
    bool operator == (cp a) const {
        return x == a.x && y == a.y;    
    }
    void read() {
        int xx, yy;
        cin >> xx >> yy;
        x = xx, y = yy;
    }
};

LD det (cp a, cp b) { return a.x * b.y - b.x * a.y; }
LD dot (cp a, cp b) { return a.x * b.x + a.y * b.y; }
LD dis (cp a, cp b) { return sqrt (sqr (a.x - b.x) + sqr(a.y - b.y)); }

bool turn_left(cp a, cp b, cp c) {
    return sgn (det (b - a, c - a)) > 0;
}

#define cl const line &
struct line {
    point s, t;
    line () {}
    line (point ss, point tt) { s = ss, t = tt; }
    bool operator == (cl a) const {
        return s == a.s && t == a.t;
    }
};

point line_inter (cl a, cl b) {
    LD s1 = det (a.t - a.s, b.s - a.s);
    LD s2 = det (a.t - a.s, b.t - a.s);
    return (b.s * s2 - b.t * s1) / (s2 - s1);
}
bool turn_left (cl l, cp p) { return turn_left(l.s, l.t, p); }

line h[8];
LD hpi_nosort() {
    line q[8]; int l = 0, r = -1;
    point ret[8];
    q[0] = h[0]; q[1] = h[1]; r = 1;
    ret[1] = line_inter(q[0], q[1]);
    for (int t = 2; t < 8; t++) {
        auto &i = h[t];
        while (l < r && !turn_left(i, ret[r]))
            -- r;
        while (l < r && !turn_left(i, ret[l + 1]))
            ++ l;
        ++ r; q[r] = i;
        if (l != r) ret[r] = line_inter(q[r - 1], q[r]);
    }
    ret[l] = line_inter(q[r], q[l]);
    LD area = 0;
    for (int i = l; i <= r; i++) area += det(ret[i], ret[i == r ? l : i + 1]);
    return area;
}


LD ans, sq;
LD check (LD x, LD y) {
    h[1] = {{-1, -y}, {1, -y}};
    h[3] = {{x, -1}, {x, 1}};
    h[5] = {{1, y}, {-1, y}};
    h[7] = {{0, 1}, {0, -1}};
    LD a = hpi_nosort();
    LD f = x * y * 4; 
    return a / (f + sq - a);
}

const LD Rp = (sqrt(5) - 1) / 2, Lp = 1 - Rp;
LD check (LD x) {
    LD l = 0, r = 1, lv = -1, rv = -1, v = 0;
    for (int t = 42; t; t--) {
        LD b = (r - l) * Rp;
        LD lmid = r - b, rmid = l + b;
        if (lv == -1) lv = check(x, lmid);
        if (rv == -1) rv = check(x, rmid);
        if (rv < lv) rv = lv, lv = -1, r = rmid;
        else lv = rv, rv = -1, l = lmid;
    }
    ans = max(ans, v = max(lv, rv));
    return v;
}


void work() {
    vector <point> p;
    for (int i = 0; i < 4; i++) {
        point u; 
        u.read();
        // u.x = eng() % 100;
        // u.y = eng() % 100;
        p.push_back(u);
    }
    if (!turn_left(p[0], p[1], p[2])) {
        reverse(p.begin(), p.end());
    }
    if (sgn(det(p[1] - p[0], {1, 0})) == 0 || sgn(det(p[2] - p[1], {1, 0})) == 0) {
        cout << "1\n";
        return;
    }
    auto center = (p[0] + p[2]) / 2;
    {
        int k = 0;
        for (int i = 0; i < 4; i++) {
            if (p[i].x < p[k].x) k = i;
        }
        vector <point> q;
        for (int i = 0; i < 4; i++) q.push_back(p[(i + k) % 4] - center);
        p = move(q);
    }
    sq = abs(det(p[1] - p[0], p[2] - p[1]));
    LD Lx = p[2].x;
    LD Ly = p[3].y;
    for (auto &[x, y] : p) {
        x /= Lx;
        y /= Ly;
    }
    sq /= Lx * Ly;

    /*{
        base[0],
        {{-1, -y}, {1, -y}},
        base[1],
        {{x, -1}, {x, 1}},
        base[2],
        {{1, y}, {-1, y}},
        base[3],
        {{0, 1}, {0, -1}}
    }*/
    h[0] = {p[0], p[1]};
    h[2] = {p[1], p[2]};
    h[4] = {p[2], p[3]};
    h[6] = {p[3], p[0]};
    LD xl = 0, xr = 1, lv = -1, rv = -1;
    ans = check(1 - 1e-9);
    for (int t = 38; t; t--) {
        LD b = (xr - xl) * Rp;
        LD lmid = xr - b, rmid = xl + b;
        if (lv == -1) lv = check(lmid);
        if (rv == -1) rv = check(rmid);
        //LD lv = check(lmid), rv = check(rmid);
        if (rv < lv) rv = lv, lv = -1, xr = rmid;
        else lv = rv, rv = -1, xl = lmid;
    }
    check((xl + xr) / 2);
    cout << (double)ans << '\n'; 
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int T = 10000;
    cin >> T;
    cout << fixed << setprecision(10);
    for (int ca = 1; ca <= T; ca ++) {
        work();
    }
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3796kb

input:

3
0 2 2 0 0 -2 -2 0
7 -2 9 -2 9 2 7 2
7 13 11 10 5 2 1 5

output:

0.7071067812
1
0.6238432248

result:

ok 3 numbers

Test #2:

score: -100
Time Limit Exceeded

input:

10000
-568767734 379152673 -565681345 -54946093 -131582579 -51859704 -134668968 382239062
-194884120 -559906233 -194884142 -158042604 -998611400 -158042648 -998611378 -559906277
459335966 -945199065 478030260 -934243779 450535683 -887326546 431841389 -898281832
-483567491 491964356 -523827401 408140...

output:

0.9929654125
0.9999999315
0.5908698157
0.6217704849
0.5788323841
1
0.4999999974
0.6852345806
0.4559617198
0.5002873939
0.9802961106
0.4920435718
0.5440373887
0.3804801071
0.9231183318
0.8925587009
0.6176803196
0.9456769702
0.4998743720
0.9999543878
0.6474214765
0.7778122048
0.5000000000
0.9560555504...

result: