White Water Rafting
题意:给出两个多边形(二维坐标),保证第一个在第二个的内部,这样两个多边形就可以组成一个环,求一个圆,能在该环内饶一周,且要求该圆的半径尽量大,输出这个半径值。
解法:明显就是求内多边形顶点到外多边形边的距离以及外多边形顶点到内多边形边的距离的最小值,即点到直线的距离
#include <iostream>
using namespace std;
#include <stdio.h>
#include <math.h>
double a[200][3], b[200][3], ans;
int n, m;
double sqr(double x) {
return x*x;
}
void count(double x1, double y1, double x2, double y2, double x, double y) {
double a1, b1, c1;
if (fabs(x1-x2) < 1e-6) {
a1 = 1; b1 = 0;
c1 = -x1;
} else {
a1 = (y2-y1)/(x2-x1);
b1 = -1;
c1 = y1-a1*x1;;
}
double len = sqrt(sqr(x1-x2)+sqr(y1-y2));
double dis = fabs(a1*x+b1*y+c1)/sqrt(a1*a1+b1*b1);
if (dis*dis+len*len < sqr(x1-x)+sqr(y1-y)) {
dis = sqrt(sqr(x2-x)+sqr(y2-y));
} else if (dis*dis+len*len < sqr(x2-x)+sqr(y2-y)) {
dis = sqrt(sqr(x1-x)+sqr(y1-y));
}
if (dis < ans) ans = dis;
}
int main() {
int tt;
cin >> tt;
for (int cases = 1; cases <= tt; cases++) {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i][1] >> a[i][2];
a[0][1] = a[n][1];
a[0][2] = a[n][2];
cin >> m;
for (int i = 1; i <= m; i++)
cin >> b[i][1] >> b[i][2];
b[0][1] = b[m][1];
b[0][2] = b[m][2];
ans = 1e9;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
count(a[i-1][1], a[i-1][2], a[i][1], a[i][2], b[j][1], b[j][2]);
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
count(b[i-1][1], b[i-1][2], b[i][1], b[i][2], a[j][1], a[j][2]);
}
}
ans = ans/2;
printf("%.10lf\n", ans);
}
}