QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#167031 | #6871. Turret | PPP# | TL | 0ms | 0kb | C++17 | 6.5kb | 2023-09-06 23:22:39 | 2023-09-06 23:22:39 |
answer
#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef 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 * X.second;
if (A < 0 || (A == 0 && B < 0)) {
A *= -1;
B *= -1;
C *= -1;
}
ll D = __gcd(llabs(A), __gcd(llabs(B), llabs(C)));
A /= D;
B /= D;
C /= D;
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-9;
auto eq = [&](ld a, ld b) {
return fabsl(a - b) < eps;
};
for (int z = 0; z < (1 << n); z++) can[z] = false;
sort(line.begin(), line.end());
line.erase(unique(line.begin(), line.end()), line.end());
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) break;
}
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;
}
详细
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...