#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
const double eps = 1e-8;
inline double delt(double a)
{
return (fabs(a) < eps ? 0 : a) > 0 ? 1 : -1;
}
#define N 1005
#define inf 1e20
using namespace std;
struct TPoint
{
double x, y;
};
inline double dist(TPoint a, TPoint b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
inline double cross(TPoint a, TPoint b, TPoint c)
{
return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}
inline double dot(TPoint a, TPoint b, TPoint c)
{
return (b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y);
}
TPoint pt[N], st, mid[N];
int n, m, t, end;
double radius;
bool scan()
{
for (int i = 0; i < n; i++)
{
scanf("%lf%lf", &pt[i].x, &pt[i].y);
}
return 1;
}
inline bool cmp(TPoint a, TPoint b)
{
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
inline bool ncmp(TPoint a, TPoint b)
{
int d1 = delt(cross(pt[0], a, b));
return d1 > 0 || (d1 == 0 && dist(pt[0], a) < dist(pt[0], b));
}
void getmove(TPoint &a, TPoint &b, double r)
{
TPoint ms;
ms.x = a.y - b.y, ms.y = b.x - a.x;
double k = r / dist(a, b);
a.x += ms.x * k, a.y += ms.y * k;
b.x += ms.x * k, b.y += ms.y * k;
}
void cut(TPoint ans[], TPoint s, TPoint e, int &np)
{
getmove(s, e, radius);
double s1, s2;
int i, j, d1, d2;
for (i = j = 0; i < np; i++)
{
s1 = cross(ans[i], s, e), s2 = cross(ans[i + 1], s, e);
d1 = delt(s1), d2 = delt(s2);
if (d1 >= 0) ans[j++] = ans[i];
if (d1 * d2 < 0)
{
ans[j].x = (s2 * ans[i].x - s1 * ans[i + 1].x) / (s2 - s1);
ans[j++].y = (s2 * ans[i].y - s1 * ans[i + 1].y) / (s2 - s1);
}
}
ans[j] = ans[0];
np = j;
}
void solve(void)
{
sort(pt, pt + n, cmp);
sort(pt, pt + n, ncmp);
int i, j, k, maxl = 0;
TPoint ans[N], a, b;
pt[n] = pt[0];
for (i = 0; i <= n; i++) ans[i] = pt[i];
for (i = 0, m = n; i < n; i++) cut(ans, pt[i], pt[i + 1], m);
if (m == 1) a = b = ans[0];
else if (m == 2) a = ans[0], b = ans[1];
else
{
double maxl = 0, l;
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
{
l = dist(ans[i], ans[j]);
if (l - maxl > eps)
{
maxl = l, a = ans[i], b = ans[j];
}
}
}
}
printf("%.4f %.4f %.4f %.4f\n", a.x, a.y, b.x, b.y);
}
int main(void)
{
while(scanf("%d%lf", &n, &radius) != EOF)
{
scan();
solve();
}
return 0;
}
题意:给出一个凸多边形的房间,根据风水要求,把两个圆形地毯铺在房间里,不能折叠,不能切割,可以重叠。问最多能覆盖多大空间,输出两个地毯的圆心坐标。多组解输出其中一个
题目保证至少可以放入一个圆,上一题中判断过在一个多边形内是否能放入一个半径为r的圆。同样将多边形的边内移R之后,半平面交区域便是可以放入圆的可行区域。题目要求覆盖的面积最大,也就是两个圆的半径相同,圆心越远,面积就越大。在半平面交区域内找到最远点对便是题目要求的解。