QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#116796 | #4886. Best Sun | hos_lyric | WA | 94ms | 7796kb | C++14 | 7.1kb | 2023-06-30 06:59:25 | 2023-06-30 06:59:28 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
int sig(Int r) { return (r < 0) ? -1 : (r > 0) ? +1 : 0; }
struct Pt {
Int x, y;
Pt() : x(0), y(0) {}
Pt(Int x_, Int y_) : x(x_), y(y_) {}
Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
Pt operator*(const Pt &a) const { return Pt(x * a.x - y * a.y, x * a.y + y * a.x); }
Pt operator+() const { return Pt(+x, +y); }
Pt operator-() const { return Pt(-x, -y); }
Pt operator*(const Int &k) const { return Pt(x * k, y * k); }
Pt operator/(const Int &k) const { return Pt(x / k, y / k); }
friend Pt operator*(const Int &k, const Pt &a) { return Pt(k * a.x, k * a.y); }
Pt &operator+=(const Pt &a) { x += a.x; y += a.y; return *this; }
Pt &operator-=(const Pt &a) { x -= a.x; y -= a.y; return *this; }
Pt &operator*=(const Pt &a) { return *this = *this * a; }
Pt &operator*=(const Int &k) { x *= k; y *= k; return *this; }
Int abs2() const { return x * x + y * y; }
Int dot(const Pt &a) const { return x * a.x + y * a.y; }
Int det(const Pt &a) const { return x * a.y - y * a.x; }
bool operator==(const Pt &a) const { return (x == a.x && y == a.y); }
bool operator<(const Pt &a) const { return (x < a.x || (x == a.x && y < a.y)); }
friend ostream &operator<<(ostream &os, const Pt &a) { os << "(" << a.x << ", " << a.y << ")"; return os; }
};
Int tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }
// (-(1/2)PI, (3/2)PI]
int cmpArg(const Pt &a, const Pt &b) {
const int sa = (a.x > 0) ? 0 : (a.x < 0) ? 2 : (a.y > 0) ? 1 : 3;
const int sb = (b.x > 0) ? 0 : (b.x < 0) ? 2 : (b.y > 0) ? 1 : 3;
return (sa < sb) ? -1 : (sa > sb) ? +1 : sig(b.det(a));
}
unsigned xrand() {
static unsigned x = 314159265, y = 358979323, z = 846264338, w = 327950288;
unsigned t = x ^ x << 11; x = y; y = z; z = w; return w = w ^ w >> 19 ^ t ^ t >> 8;
}
using Double = double;
constexpr Double INF = 1e+20;
int N;
vector<Pt> P;
Double D[310][310];
char S[310][310][310];
// inside triangle 0, i, j
int cnt[310][310];
// inside triangle i, j, k
int enclose(int i, int j, int k) {
int ret = 0;
ret += cnt[i][j];
ret += cnt[j][k];
ret += cnt[k][i];
ret -= (S[0][j][i] + S[j][k][i] + S[k][0][i]) / 3;
ret -= (S[0][k][j] + S[k][i][j] + S[i][0][j]) / 3;
ret -= (S[0][i][k] + S[i][j][k] + S[j][0][k]) / 3;
#ifdef LOCAL
int brt=0;
for(int l=0;l<N;++l)brt+=abs((S[i][j][l]+S[j][k][l]+S[k][i][l])/3);
if(brt!=ret)cerr<<P[i]<<" "<<P[j]<<" "<<P[k]<<": "<<brt<<" "<<ret<<endl;
assert(brt==ret);
#endif
return ret;
}
Double cost[310][310];
using Dir = pair<Pt, pair<int, pair<int, int>>>;
vector<Dir> dirs;
// s: min (x, y)
// area - ratio * length >= 0
bool check(int src, Double ratio) {
vector<Double> dp(N, -INF);
Double mx = -INF;
dp[src] = 0.0;
for (const auto &dir : dirs) {
const int i = dir.second.second.first;
const int j = dir.second.second.second;
if (dir.second.first == 0) {
if (S[src][i][j] >= 0 && enclose(src, i, j) == 0) {
chmax((src == j) ? mx : dp[j], dp[i] + tri(P[src], P[i], P[j]) / 2.0 - ratio * cost[i][j]);
}
} else {
dp[i] -= ratio * D[i][j];
}
}
return (mx >= 0.0);
}
int main() {
for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) {
scanf("%d", &N);
P.resize(N);
for (int i = 0; i < N; ++i) {
scanf("%lld%lld", &P[i].x, &P[i].y);
}
sort(P.begin(), P.end());
for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {
D[i][j] = sqrt((Double)(P[j] - P[i]).abs2());
}
for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) for (int k = 0; k < N; ++k) {
S[i][j][k] = sig(tri(P[i], P[j], P[k]));
}
for (int i = 0; i < N; ++i) {
fill(cnt[i], cnt[i] + N, 0);
}
for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) if (S[0][i][j] > 0) {
for (int k = 0; k < N; ++k) {
cnt[i][j] += (S[0][i][k] + S[i][j][k] + S[j][0][k]) / 3;
}
cnt[j][i] = -cnt[i][j];
}
// if(N<=3)for(int i=0;i<N;++i)for(int j=0;j<N;++j)for(int k=0;k<N;++k)cerr<<i<<" "<<j<<" "<<k<<": "<<enclose(i,j,k)<<endl;
/*
cost of j at corner i:
- come in [arg(P[j] - P[i]) - PI/2, arg(P[j] - P[i]) + PI/2]
- go in [arg(P[j] - P[i]) + PI/2, arg(P[j] - P[i]) - PI/2]
for src != i
impose when: come <= arg(P[j] - P[i]) + PI/2 < go
(ignore non-convex turning)
remaining cost: projected on the segment [i, j)
*/
// projected on the segment
for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {
cost[i][j] = D[i][j];
for (int k = 0; k < N; ++k) {
if (S[i][j][k] < 0 &&
(P[j] - P[i]).dot(P[k] - P[i]) >= 0 &&
(P[i] - P[j]).dot(P[k] - P[j]) > 0) {
cost[i][j] += min(D[i][k], D[j][k]);
}
}
}
dirs.clear();
for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) if (i != j) {
dirs.emplace_back(P[j] - P[i], make_pair(0, make_pair(i, j)));
dirs.emplace_back((P[j] - P[i]) * Pt(0, 1), make_pair(1, make_pair(i, j)));
}
sort(dirs.begin(), dirs.end(), [&](const Dir &dir0, const Dir &dir1) -> bool {
const int s = cmpArg(dir0.first, dir1.first);
return (s ? (s < 0) : (dir0.second < dir1.second));
});
// cerr<<"dirs = "<<dirs<<endl;
vector<int> ss(N);
for (int i = 0; i < N; ++i) {
swap(ss[xrand() % (i + 1)], ss[i] = i);
}
Double lo = 0.0;
for (const int s : ss) {
if (check(s, lo)) {
Double hi = 1e+9;
for (int iter = 0; iter < 60; ++iter) {
const Double mid = (lo + hi) / 2.0;
(check(s, mid) ? lo : hi) = mid;
}
}
}
printf("%.12f\n", lo);
}
#ifndef LOCAL
break;
#endif
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 7796kb
input:
4 3 -1 -1 1 -1 0 1 4 0 0 10 0 0 10 8 1 5 2 0 -2 0 1 1 -1 1 0 3 8 4 4 -4 4 4 -4 -4 -4 5 6 -6 5 -5 -6 6 -5
output:
0.309016994285 1.236861427514 0.271137541238 1.563100209420
result:
ok 4 numbers
Test #2:
score: 0
Accepted
time: 82ms
memory: 3816kb
input:
10000 3 702262 828158 -350821 -420883 -466450 13507 3 28647 -193498 126436 -864937 -287798 738936 3 270358 -269567 745815 -485408 834083 677952 3 -2036 -403634 742978 -263774 975937 -609237 3 584248 -472620 482016 -356760 284902 903881 3 -292004 504925 -935756 373793 -781101 -434659 3 -858513 684433...
output:
85789.087398353484 18268.519361671824 102489.988390261860 66685.754428079395 18674.657937413525 106468.965131971927 14427.024651070264 29966.245302542360 143547.751083586772 13097.175688125615 162410.168316980125 72070.932417874283 29369.992627886582 52867.294431100876 90314.308346756327 99775.92719...
result:
ok 10000 numbers
Test #3:
score: 0
Accepted
time: 82ms
memory: 3816kb
input:
10000 3 2 2 2 -2 -5 -5 3 -3 5 5 -4 2 -2 3 -4 1 2 -2 -4 4 3 1 -4 2 1 -4 1 3 2 1 -1 1 -3 3 3 4 5 3 -1 -3 -3 3 1 5 5 0 5 -1 3 2 -3 -5 -3 5 3 3 -4 4 0 -5 5 4 3 2 -3 5 0 2 -5 3 -2 -3 5 -3 5 4 3 -1 4 4 4 4 3 3 5 3 -1 4 2 -1 3 2 -3 4 3 -4 3 3 0 4 -2 -2 -1 -3 3 -2 0 -4 -2 4 2 3 -3 -1 3 1 1 -3 3 2 -5 2 3 -4 ...
output:
0.650700700787 0.226809069789 0.494682565744 0.825532630970 0.267532474472 0.737928456188 0.136852946510 0.827745795517 1.389628120040 0.248476165858 1.025126265125 0.225245121166 0.798168850458 1.052177633215 0.270090756184 0.221028003192 0.654929147373 1.065792545364 0.120736187541 0.172721212333 ...
result:
ok 10000 numbers
Test #4:
score: -100
Wrong Answer
time: 94ms
memory: 5796kb
input:
5625 4 -405394 -381883 602267 -335687 -620806 984110 271283 531233 4 196903 -993060 290851 358123 -890076 -717709 -681138 209884 4 -849589 607722 -21517 -586295 208561 -220953 924518 622983 4 -832186 456270 289934 43656 636006 339718 188963 113907 4 -305762 -872205 -520125 368722 -774548 984204 4245...
output:
232625.004274430394 268175.826985963213 159589.323630517232 60440.753042598313 160077.128456144186 63201.990748626078 167697.663406134292 129470.013284315559 126903.854072810122 120109.808780404855 131692.311227904691 100421.055016211729 148490.274817902071 68842.242309822439 241376.191116128699 303...
result:
wrong answer 5th numbers differ - expected: '133893.1234364', found: '160077.1284561', error = '0.1955590'