ARC 181 | F - Silver Woods
문제.
생각
반지름 r의 원을 y=-100에서 y=100 사이로 이동합니다.그 사이에 못이 있다.아래와 같은 그림.
반경 r의 원은 아래와 같이 녹색으로 둘러싸일 수 있는지, 점과 점 사이가 반경 r보다 작은 점의 집합을 통해 상하의 직선의 가장 짧은 지점의 점start와 goal을 각각 더할 수 있는지, start에서 goal까지의 가장 긴 거리의\racc{1}는 원을 통과할 수 있는 최대 반경이다.
가장 작은 r는 r\(0
코드
설치는 그리 어렵지 않다.
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
const int MOD = 1e9 + 7;
int main() {
ll n;
cin >> n;
vector<vector<ld>> p(n, vector<ld>(2)); // (x, y)の配列
for (int i = 0; i < n; i++) {
cin >> p[i][0] >> p[i][1];
}
vector<pair<ld, vector<int>>> d; // (d, (i, j)): dはp[i],p[j]間の距離
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
ld v = sqrt(pow(p[i][0] - p[j][0], 2) + pow(p[i][1] - p[j][1], 2));
d.push_back({v, {i, j}});
}
}
sort(d.begin(), d.end());
ld left = 0;
ld right = 200; // 直径の最大
ld cnt = 100;
while (cnt > 0) {
// 二分探索
ld mid = (left + right) / 2;
dsu uf(n);
for (int i = 0; i < d.size(); i++) {
if (mid < d[i].first) {
break;
}
// 線分をつなげる
uf.merge(d[i].second[0], d[i].second[1]);
}
// グループごとにy=-100とy=100との最小距離を確認してそれがmidより小さかったら通れない
bool possible = true;
for (auto group : uf.groups()) {
ld minY = 100;
ld maxY = -100;
for (int i : group) {
minY = min(minY, p[i][1]);
maxY = max(maxY, p[i][1]);
}
if (abs(-100 - minY) < mid && abs(100 - maxY) < mid) {
possible = false;
}
}
if (possible) {
left = mid;
} else {
right = mid;
}
cnt--;
}
cout << fixed << std::setprecision(12);
cout << left / 2 << endl;
}
참고 자료
Reference
이 문제에 관하여(ARC 181 | F - Silver Woods), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/wapa5pow/articles/abc181-f-219cc28713e84a352765텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)