Trash Removal uva1111/uvalive5138 World Final 2011 K 计算几何

来源:互联网 发布:做微商好还是做淘宝好 编辑:程序博客网 时间:2024/06/07 23:34

题目:https://cn.vjudge.net/problem/UVA-1111

题意:扔垃圾,垃圾的形状是(凹凸)多边形,给出多边形的顶点坐标,求最小的垃圾桶宽度,使垃圾能够进入(垃圾可以旋转)。保证输入线段不相交,无重复点。输出精确到小数点后两位。

思路:观察题目给出的例图,可以发现当多边形轮廓(即凸包)上的边紧贴垃圾桶壁时肯定比所有边都不与桶壁平行要好。在此基础上,只要离这条边距离最远的点能通过垃圾桶,那整个多边形就能通过。
那么做法就出来了,对给出的点求凸包,枚举凸包上的边,求其余各点到这条边的最远距离,这些距离中最小的即为答案。
另外有个小细节,既然需要让多边形通过,精确小数时不是四舍五入,需要向上取整。

代码:c++

#include <cstdio>#include <cstring>#include <iostream>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <set>#include <map>using namespace std;const double eps = 1e-8;int dcmp(double a){    if(fabs(a) < eps)    {        return 0;    }    return a > 0 ? 1 : -1;}struct Point{    double x, y;    Point(double xx = 0, double yy = 0): x(xx), y(yy) {}    bool operator < (const Point &t) const    {        return make_pair(x, y) < make_pair(t.x, t.y);    }    void show()    {        printf("(%g, %g)\n", x, y);    }};typedef Point Vector;Vector operator - (Point A, Point B){    return Vector(A.x - B.x, A.y - B.y);}Vector operator * (Vector A, double p){    return Vector(A.x * p, A.x * p);}bool operator == (const Point &A, const Point &B){    return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0;}double Dot(Vector A, Vector B){    return A.x * B.x + A.y * B.y;}double Length(Vector v){    return sqrt(Dot(v, v));}double Cross(Vector A, Vector B){    return A.x * B.y - A.y * B.x;}double DistanceToLine(Point p, Point A, Point B){    Vector v1 = B - A;    Vector v2 = p - A;    return fabs(Cross(v1, v2)) / Length(v1);}void ConvexHull(vector<Point> &p, vector<Point> &hull){    sort(p.begin(), p.end());    for(int i = 0; i < p.size(); i++)    {        while(hull.size() > 1 && Cross(hull.back() - hull[hull.size() - 2], p[i] - hull[hull.size() - 2]) <= 0)        {            hull.pop_back();        }        hull.push_back(p[i]);    }    int k = hull.size();    for(int i = p.size() - 2; i >= 0; i--)    {        while(hull.size() > k && Cross(hull.back() - hull[hull.size() - 2], p[i] - hull[hull.size() - 2]) <= 0)        {            hull.pop_back();        }        hull.push_back(p[i]);    }    if(!hull.empty())    {        hull.pop_back();    }}vector<Point> p;vector<Point> hull;double LongestDistance(int p1, int p2){    double maxx = 0;    for(int i = 0; i < hull.size(); i++)    {        if(i == p1 || i == p2)        {            continue;        }        maxx = max(maxx, DistanceToLine(hull[i], hull[p1], hull[p2]));    }    return maxx;}int main(){    int n;    int cases = 1;    while(scanf("%d", &n) != EOF && n)    {        p.clear();        hull.clear();        for(int i = 0; i < n; i++)        {            double x, y;            scanf("%lf%lf", &x, &y);            p.push_back(Point(x, y));        }        ConvexHull(p, hull);        double minn = LongestDistance(0, hull.size() - 1);        for(int i = 0; i < hull.size() - 1; i++)        {            minn = min(minn, LongestDistance(i, i + 1));        }        printf("Case %d: %.2f\n", cases++, 0.01 * ceil(minn * 100));    }    return 0;}
原创粉丝点击