QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#275719#7906. Almost ConvexMonohydroxidesWA 4ms3596kbC++206.9kb2023-12-04 23:43:562023-12-04 23:43:56

Judging History

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

  • [2023-12-04 23:43:56]
  • 评测
  • 测评结果:WA
  • 用时:4ms
  • 内存:3596kb
  • [2023-12-04 23:43:56]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using db = long double;

// db eps = 1e-14;
// db pi = acos(-1);

// int sign(db a) {
//     return a < -eps ? -1 : a > eps;
// }

// int cmp(db a, db b) {
//     return sign(a - b);
// }

struct Points {
    i64 x, y;
    
    Points(i64 _x = 0., i64 _y = 0.) : x(_x), y(_y) {}
    
    // int operator<(const Points &rhs) const {
    //     int c = cmp(x, rhs.x);
    //     if (c) {
    //         return c == -1;
    //     }
    //     return cmp(y, rhs.y) == -1;
    // }
    int operator<(const Points &rhs) const {
        return x == rhs.x ? y < rhs.y : x < rhs.x;
    }
};

Points operator+(Points a, Points b) {
    return Points(a.x + b.x, a.y + b.y);
}

Points operator-(Points a, Points b) {
    return Points(a.x - b.x, a.y - b.y);
}

// db dot(Points a, Points b) {
//     return a.x * b.x + a.y * b.y;
// }

i64 dot(Points a, Points b) {
    return a.x * b.x + a.y * b.y;
}

// db Cross(Points a, Points b) {
//     return a.x * b.y - a.y * b.x;
// }

i64 Cross(Points a, Points b) {
    return a.x * b.y - a.y * b.x;
}

// db len(Points a) {
//     return sqrt(dot(a, a));
// }

// Points rotate(Points p, db angle) {
//     return Points(p.x * cos(angle) - p.y * sin(angle), p.x * sin(angle) + p.y * cos(angle));
// }

// db Angle(Points a, Points b) {
//     return acos(dot(a, b) / len(a) / len(b));
// }

// int quad(Points a) {
//     return sign(a.y) == 1 || (sign(a.y) == 0 && sign(a.x) >= 0);
// }

// db Cross(Points p1, Points p2, Points p3) {
//     return ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y));
// }

i64 Cross(Points p1, Points p2, Points p3) {
    return ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y));
}

// int crossOp(Points p1, Points p2, Points p3) {
//     return sign(Cross(p1, p2, p3));
// }

int crossOp(Points p1, Points p2, Points p3) {
    i64 c = Cross(p1, p2, p3);
    if (c < 0) {
        return -1;
    } else if (c == 0) {
        return 0;
    }
    return 1;
}

// bool isMiddle(db a, db m, db b) {
//     return sign(a - m) == 0 || sign(b - m) == 0 || (a < m != b < m);
// }

bool isMiddle(i64 a, i64 m, i64 b) {
    return a == m || b == m || (a < m != b < m);
}

bool isMiddle(Points a, Points m, Points b) {
    return isMiddle(a.x, m.x, b.x) && isMiddle(a.y, m.y, b.y);
}

bool OnSeg(Points p1, Points p2, Points q) {
    return crossOp(p1, p2, q) == 0 && isMiddle(p1, q, p2);
}

vector<Points> convex_hell(vector<Points> &pts) {
    sort(pts.begin(), pts.end());
    int n = pts.size(), m = 0;
    vector<Points> ch;
    for (int i = 0; i < n; i++) {
        while (m > 1 && Cross(ch[m - 1] - ch[m - 2], pts[i] - ch[m - 2]) <= 0) {
            ch.pop_back();
            m--;
        }
        ch.push_back(pts[i]);
        m++;
    }
    int k = m;
    for (int i = n - 2; i >= 0; i--) {
        while (m > k && Cross(ch[m - 1] - ch[m - 2], pts[i] - ch[m - 2]) <= 0) {
            ch.pop_back();
            m--;
        }
        ch.push_back(pts[i]);
        m++;
    }
    if (n > 1) {
        ch.pop_back();
        m--;
    }
    return ch;
}

// int pointsInPoly(vector<Points> &p, Points a) {
//     int n = p.size(), ret = 0;
//     for (int i = 0; i < n; i++) {
//         Points u = p[i], v = p[(i + 1) % n];
//         if (OnSeg(u, v, a)) {
//             assert(0);
//             return 1;
//         }
//         if (cmp(u.y, v.y) <= 0) {
//             swap(u, v);
//         }
//         if (cmp(a.y, u.y) > 0 || cmp(a.y, v.y) <= 0) {
//             continue;
//         }
//         ret ^= crossOp(a, u, v) > 0;
//     }
//     return ret * 2;
// }

int pointsInPoly(vector<Points> &p, Points a) {
    int n = p.size(), ret = 0;
    for (int i = 0; i < n; i++) {
        Points u = p[i], v = p[(i + 1) % n];
        if (OnSeg(u, v, a)) {
            assert(0);
            return 1;
        }
        if (u.y <= v.y) {
            swap(u, v);
        }
        if (a.y > u.y || a.y <= v.y) {
            continue;
        }
        ret ^= crossOp(a, u, v) > 0;
    }
    return ret * 2;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    vector<Points> pts;
    for (int i = 1; i <= n; i++) {
        int x, y;
        cin >> x >> y;
        pts.push_back(Points(double(x), double(y)));
    }
    auto ch = convex_hell(pts);
    vector<Points> notOnConvVec;
    map<Points, bool> onConv;
    for (int i = 0; i < ch.size(); i++) {
        onConv[ch[i]] = 1;
    }
    for (int i = 0; i < pts.size(); i++) {
        if (!onConv.count(pts[i])) {
            notOnConvVec.push_back(pts[i]);
        }
    }
    if (notOnConvVec.size() == 0) {
        cout << 1 << "\n";
        return 0;
    }
    int ans = 1;
    // auto process = [&](vector<Points> &pts, Points a, Points b) {
    //     // db angle = Angle(Points(1.0, 0.0), b - a);
    //     for (int i = 0; i < pts.size(); i++) {
    //         pts[i] = pts[i] - a;
    //         // pts[i] = rotate(pts[i], 2 * pi - angle);
    //     }
    //     sort(pts.begin(), pts.end(), [](Points a, Points b) {
    //         // int qa = quad(a), qb = quad(b);
    //         // if (qa != qb) {
    //         //     return qa < qb;
    //         // } else {
    //         //     return sign(Cross(a, b)) > 0;
    //         // }
    //         return cmp(Cross(a, b), 0.) > 0;
    //     });
    //     for (int i = 0; i < pts.size(); i++) {
    //         // pts[i] = rotate(pts[i], angle);
    //         pts[i] = pts[i] + a;
    //     }
    // };
    auto process = [&](vector<Points> &pts, Points a, Points b) {
        // db angle = Angle(Points(1.0, 0.0), b - a);
        for (int i = 0; i < pts.size(); i++) {
            pts[i] = pts[i] - a;
            // pts[i] = rotate(pts[i], 2 * pi - angle);
        }
        sort(pts.begin(), pts.end(), [](Points a, Points b) {
            // int qa = quad(a), qb = quad(b);
            // if (qa != qb) {
            //     return qa < qb;
            // } else {
            //     return sign(Cross(a, b)) > 0;
            // }
            return Cross(a, b) > 0;
        });
        for (int i = 0; i < pts.size(); i++) {
            // pts[i] = rotate(pts[i], angle);
            pts[i] = pts[i] + a;
        }
    };
    for (int i = 0; i < ch.size(); i++) {
        process(notOnConvVec, ch[i], ch[(i + 1) % ch.size()]);
        vector<Points> tmp;
        tmp.push_back(ch[i]);
        tmp.push_back(ch[(i + 1) % ch.size()]);
        ans++;
        for (int j = 1; j < notOnConvVec.size(); j++) {
            if (Cross(notOnConvVec[j] - ch[(i + 1) % ch.size()], notOnConvVec[j - 1] - ch[(i + 1) % ch.size()]) < 0) {
                ans++;
            }
        }
    }
    cout << ans << "\n";
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3520kb

input:

7
1 4
4 0
2 3
3 1
3 5
0 0
2 4

output:

9

result:

ok 1 number(s): "9"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3500kb

input:

5
4 0
0 0
2 1
3 3
3 1

output:

5

result:

ok 1 number(s): "5"

Test #3:

score: 0
Accepted
time: 0ms
memory: 3480kb

input:

3
0 0
3 0
0 3

output:

1

result:

ok 1 number(s): "1"

Test #4:

score: 0
Accepted
time: 1ms
memory: 3444kb

input:

6
0 0
3 0
3 2
0 2
1 1
2 1

output:

7

result:

ok 1 number(s): "7"

Test #5:

score: 0
Accepted
time: 0ms
memory: 3496kb

input:

4
0 0
0 3
3 0
3 3

output:

1

result:

ok 1 number(s): "1"

Test #6:

score: -100
Wrong Answer
time: 4ms
memory: 3596kb

input:

2000
86166 617851
383354 -277127
844986 386868
-577988 453392
-341125 -386775
-543914 -210860
-429613 606701
-343534 893727
841399 339305
446761 -327040
-218558 -907983
787284 361823
950395 287044
-351577 -843823
-198755 138512
-306560 -483261
-487474 -857400
885637 -240518
-297576 603522
-748283 33...

output:

43932

result:

wrong answer 1st numbers differ - expected: '718', found: '43932'