QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#167025#6871. TurretPPP#TL 0ms0kbC++176.1kb2023-09-06 23:13:282023-09-06 23:13:29

Judging History

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

  • [2023-09-06 23:13:29]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2023-09-06 23:13:28]
  • 提交

answer

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
//#pragma GCC optimize("O3")
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
const int mod = 998244353;

int mult(int a, int b) {
    return (1LL * a * b) % mod;
}

int sub(int a, int b) {
    int s = a - b;
    if (s < 0) s += mod;
    return s;
}

int pw(int a, int b) {
    if (b == 0) return 1;
    if (b & 1) return mult(a, pw(a, b - 1));
    int res = pw(a, b / 2);
    return mult(res, res);
}

int sum(int a, int b) {
    int s = a + b;
    if (s >= mod) s -= mod;
    return s;
}

int n, m;
const int maxN = 22;
int x[maxN][maxN];
int y[maxN][maxN];
vector<pair<int,int>> poly[maxN];
bool can[(1 << 15) + 2];
int dp[(1 << 15) + 2];
void solve() {
    cin >> n;
    vector<pair<int,int>> cands;
    vector<pair<int,int>> good;
    for (int i = 0; i < n; i++) {
        int sz;
        cin >> sz;
        poly[i].resize(sz);
        for (auto& it : poly[i]) {
            cin >> it.first >> it.second;
            cands.emplace_back(it);
        }
        good.emplace_back(poly[i][0]);
    }
    cands.emplace_back(0, 0);
    good.emplace_back(0, 0);
    cands.emplace_back(10000, 10000);
    good.emplace_back(10000, 10000);
    cands.emplace_back(0, 10000);
    good.emplace_back(0, 10000);
    cands.emplace_back(10000, 0);
    good.emplace_back(10000, 0);

    sort(cands.begin(), cands.end());
    cands.erase(unique(cands.begin(), cands.end()), cands.end());

    sort(good.begin(), good.end());
    good.erase(unique(good.begin(), good.end()), good.end());
    vector<tuple<ll,ll,ll>> line;
    for (int i = 0; i < cands.size(); i++) {
        for (int j = 0; j < good.size(); j++) {
            if (cands[i] == good[j]) continue;
            auto X = cands[i];
            auto Y = good[j];
            ll A = Y.second - X.second;
            ll B = X.first - Y.first;
            ll C = -A * X.first - B * Y.first;
            line.emplace_back(make_tuple(A, B, C));
        }
    }

    auto det = [&](ll a11, ll a12, ll a21, ll a22) {
        return a11 * a22 - a21 * a12;
    };

    const ld eps = 1e-12;
    auto eq = [&](ld a, ld b) {
        return fabsl(a - b) < eps;
    };
    for (int z = 0; z < (1 << n); z++) can[z] = false;
    for (auto& it : line) {
        for (auto& jit : line) {
            if (it >= jit) continue;
            ll A1 = get<0>(it);
            ll B1 = get<1>(it);
            ll C1 = get<2>(it);

            ll A2 = get<0>(jit);
            ll B2 = get<1>(jit);
            ll C2 = get<2>(jit);

            ll D = det(A1, B1, A2, B2);
            if (D == 0) continue;
            ll D1 = det(-C1, B1, -C2, B2);
            ll D2 = det(A1, -C1, A2, -C2);
            if (D < 0) {
                D *= -1;
                D1 *= -1;
                D2 *= -1;
            }
            if (D1 < 0 || D2 < 0 || D1 > 10000 * D || D2 > 10000 * D) continue;
            ld x = (ld)D1 / D;
            ld y = (ld)D2 / D;
            int msk = 0;
            for (int t = 0; t < n; t++) {
                bool good = true;
                bool has_equal = false;
                for (int j = 0; j < n; j++) {
                    ld dx = (poly[t][0].first - x);
                    ld dy = (poly[t][0].second - y);
                    if (fabsl(dx) < eps && fabsl(dy) < eps) {
                        break;
                    }
                    ld L = 0;
                    ld R = 1;
                    for (int f = 0; f < poly[j].size(); f++) {
                        auto t1 = poly[j][f];
                        auto t2 = poly[j][(f + 1) % poly[j].size()];
                        ll A = t2.second - t1.second;
                        ll B = t1.first - t2.first;
                        ll C = -A * t1.first - B * t1.second;
                        A *= -1;
                        B *= -1;
                        C *= -1;
                        auto t3 = poly[j][(f + 2) % poly[j].size()];
                        assert(t3.first * A + t3.second * B + C > 0);
                        ld coef = A * dx + B * dy;
                        ld val = A * x + B * y + C;
                        if (fabsl(coef) < eps) {
                            if (fabsl(val) < eps) {
                                has_equal = true;
                                break;
                            }
                        }
                        else {
                            if (coef > eps) {
                                L = max(L, -val / coef);
                            }
                            else {
                                R = min(R, -val / coef);
                            }
                        }
                    }
                    if (L + eps < R && !has_equal) {
                        good = false;
                        break;
                    }
                }
                if (good) {
                    msk |= (1 << t);
                }
            }
            can[msk] = true;
        }
    }
    for (int bit = 0; bit < n; bit++) {
        for (int mask = 0; mask < (1 << n); mask++) {
            if (mask & (1 << bit)) {
                can[mask ^ (1 << bit)] |= can[mask];
            }
        }
    }
    const int INF = 1e9;
    for (int mask = 0; mask < (1 << n); mask++) {
        if (can[mask]) {
            dp[mask] = 1;
        }
        else {
            dp[mask] = INF;
        }
    }
    for (int mask = 0; mask < (1 << n); mask++) {
        if (dp[mask] == INF) continue;
        int sb = ((1 << n) - 1) ^ mask;
        while (true) {
            if (can[sb]) {
                dp[mask | sb] = min(dp[mask | sb], dp[mask] + 1);
            }
            if (sb == 0) break;
            sb = (((1 << n) - 1) ^ mask) & (sb - 1);
        }
    }
    cout << dp[(1 << n) - 1] << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#ifdef DEBUG
    freopen("input.txt", "r", stdin);
#endif
    int tst;
    cin >> tst;
    while (tst--) {
        solve();
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

input:

10
5
8
3640 2337
5128 1817
5228 1863
5188 2765
5034 3655
4384 3715
3802 3251
3682 2579
7
2343 5705
799 5745
579 4193
1179 3837
1513 3787
2221 3991
2331 4137
7
5734 6064
6136 5810
7396 5930
7588 6328
7534 7074
6512 7708
5726 7376
8
9256 2017
8606 2473
8032 2291
7374 1869
7328 1605
7462 1123
8056 1063...

output:


result: