1.题目描述:
给你一个凸多边形,然后要你求最大的D,使得所有的点分别沿着任意方向移动D,多边形仍然是凸多边形。
3.解题思路:
对于相邻三个点,考虑移动中间那个点,当移动到它们三点共线时候一定是一个临界条件D,那么O(N)的更新每个顶点的临界条件即可。
对于到临界条件D的计算用到了叉乘。对于向量AxB表示以A和B为边的平行四边形面积,然后再算出这个平行四边形的高就是顶点移动到三点共线所需要移动的最小距离D。
4.AC代码:
#include <bits/stdc++.h>
#define INF 1e18
#define maxn 100100
#define lson root << 1
#define rson root << 1 | 1
#define lent (t[root].r - t[root].l + 1)
#define lenl (t[lson].r - t[lson].l + 1)
#define lenr (t[rson].r - t[rson].l + 1)
#define N 1111
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
typedef unsigned long long ull;
struct point
{
double x, y;
point() {}
point(double a, double b) { x = a; y = b; }
friend point operator- (point a, point b)
{
return point(a.x - b.x, a.y - b.y);
}
friend point operator+ (point a, point b)
{
return point(a.x + b.x, a.y + b.y);
}
friend double operator* (point a, point b)
{
return a.x * b.y - b.x * a.y;
}
} p[N];
double getdis(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
long _begin_time = clock();
#endif
int n;
while (~scanf("%d", &n))
{
for (int i = 0; i < n; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
for (int i = n; i < n + 2; i++)
p[i] = p[i - n];
double ans = INF;
for (int i = 0; i < n; i++)
{
double tmp = (p[i + 2] - p[i]) * (p[i + 1] - p[i]) / 2.0 / getdis(p[i + 2], p[i]);
ans = min(ans, tmp);
}
printf("%.10f\n", ans);
}
#ifndef ONLINE_JUDGE
long _end_time = clock();
printf("time = %ld ms.", _end_time - _begin_time);
#endif
return 0;
}