Найдите круг наибольшего радиуса, который можно полностью поместить в заданный выпуклый многоугольник
Найдите круг наибольшего радиуса, который можно полностью поместить в заданный выпуклый многоугольник
Формат ввода В первой строке записано число вершин в многоугольнике N(3≤N≤10000). Следующие N строк содержат пары целых чисел xi and yi, не превосходящие по модулю 10^7 — координаты вершин выпуклого многоугольника в порядке обхода против часовой стрелке. Никакие три вершины не лежат на одной прямой.
Формат вывода Выведите радиус искомого круга с точностью 4 знака после запятой.
4
0 0
1 0
1 1
0 1
0.500000000000
Вот мой код, он даёт неверный ответ на 6 тесте, помогите пожалуйста исправить ошибку
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <set>
#include <iomanip>
using namespace std;
typedef long double ld;
const ld EPS = 1E-10;
const ld PI = 3.14;
struct pt {
ld x, y;
pt() { }
pt(ld x, ld y) : x(x), y(y) { }
pt operator- (const pt& p) const {
return pt(x - p.x, y - p.y);
}
};
istream& operator >>(istream& in, pt& p) {
in >> p.x >> p.y;
return in;
}
ld dist(const pt& a, const pt& b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
ld get_ang(const pt& a, const pt& b) {
ld ang = abs(atan2(a.y, a.x) - atan2(b.y, b.x));
return min(ang, 2 * PI - ang);
}
struct line {
ld a, b, c;
line(const pt& p, const pt& q) {
a = p.y - q.y;
b = q.x - p.x;
c = -a * p.x - b * p.y;
ld z = sqrt(a * a + b * b);
a /= z, b /= z, c /= z;
}
};
ld det(ld a, ld b, ld c, ld d) {
return a * d - b * c;
}
pt intersect(const line& n, const line& m) {
ld zn = det(n.a, n.b, m.a, m.b);
return pt(
-det(n.c, n.b, m.c, m.b) / zn,
-det(n.a, n.c, m.a, m.c) / zn
);
}
bool parallel(const line& n, const line& m) {
return abs(det(n.a, n.b, m.a, m.b)) < EPS;
}
ld get_h(const pt& p1, const pt& p2,
const pt& l1, const pt& l2, const pt& r1, const pt& r2)
{
pt q1 = intersect(line(p1, p2), line(l1, l2));
pt q2 = intersect(line(p1, p2), line(r1, r2));
ld l = dist(q1, q2);
ld alpha = get_ang(l2 - l1, p2 - p1) / 2;
ld beta = get_ang(r2 - r1, p1 - p2) / 2;
return l * sin(alpha) * sin(beta) / sin(alpha + beta);
}
struct cmp {
bool operator() (const pair<ld, int>& a, const pair<ld, int>& b) const {
if (abs(a.first - b.first) > EPS)
return a.first < b.first;
return a.second < b.second;
}
};
int main() {
int n;
cin >> n;
vector<pt> p(n);
for (pt& i : p) {
cin >> i;
}
vector<int> next(n), prev(n);
for (int i = 0; i < n; ++i) {
next[i] = (i + 1) % n;
prev[i] = (i - 1 + n) % n;
}
set < pair<ld, int>, cmp > q;
vector<ld> h(n);
for (int i = 0; i < n; ++i) {
h[i] = get_h(
p[i], p[next[i]],
p[i], p[prev[i]],
p[next[i]], p[next[next[i]]]
);
q.insert(make_pair(h[i], i));
}
ld last_time;
while (q.size() > 2) {
last_time = q.begin()->first;
int i = q.begin()->second;
q.erase(q.begin());
next[prev[i]] = next[i];
prev[next[i]] = prev[i];
int nxt = next[i], nxt1 = (nxt + 1) % n,
prv = prev[i], prv1 = (prv + 1) % n;
if (parallel(line(p[nxt], p[nxt1]), line(p[prv], p[prv1])))
break;
q.erase(make_pair(h[nxt], nxt));
q.erase(make_pair(h[prv], prv));
h[nxt] = get_h(
p[nxt], p[nxt1],
p[prv1], p[prv],
p[next[nxt]], p[(next[nxt] + 1) % n]
);
h[prv] = get_h(
p[prv], p[prv1],
p[(prev[prv] + 1) % n], p[prev[prv]],
p[nxt], p[nxt1]
);
q.insert(make_pair(h[nxt], nxt));
q.insert(make_pair(h[prv], prv));
}
cout << fixed << setprecision(4) << last_time << endl;
}
Ответы (1 шт):
Автор решения: a_nR1085__i
→ Ссылка
То есть нужно найти радиус вписанной окружности. Это площадь / полупериметр:
ld radius(vector<pt> points) //радиус вписанной окружности
{
ld sq = 0; //площадь многоугольника
ld p = 0; // периметр
for (unsigned int i = 0; i < points.size(); i++)
{
pt p1 = points[i];
pt p2 = points[(i + 1 < points.size() ? i + 1 : 0)];
sq += (p1.x + p2.x) * (p2.y - p1.y);
p += dist(p1, p2);
}
sq = abs(sq) / 2;
return sq / (p / 2); // площадь на полупериметр
}