zoukankan      html  css  js  c++  java
  • ALGO-185 Trash Removal

    ```
    算法训练 Trash Removal
    时间限制:1.0s 内存限制:256.0MB

    问题描述
      Allied Chute公司是一个建造垃圾管道的公司。垃圾管道建造在楼房中,垃圾从顶部进入,顺着管道与地下室连接。建造垃圾管道是一个高水平的工作。根据人们丢入不同种类的垃圾,垃圾管道需要有一个适当的尺寸。并且由于制作垃圾管道的费用正比于它的尺寸,公司总是想要建造尽可能的管道,尽管确定合适的尺寸十分困难。
      为了简化这个问题,我们考虑一个二维的空间。垃圾管道是一个有着固定宽度、垂直下降的槽。物体可以看作一个多边形的模型。在物体落入管道之前它可以旋转来达到和管道最佳拟合。当它下落时,它会垂直落下并且不再旋转。下图展示了一个垃圾是怎样旋转来符合管道的。
      你的任务是计算让一个给定的多边形物体通过的最小管道宽度。
    输入格式
      输入包含多组数据。每组数据开始于一个数字n,代表垃圾的模型—一个多边形的顶点数。
      接下来n行每行一对整数xi和yi,按顺序给出多边形的顶点。
      最后以一个0表示结束
    输出格式
      对于每组测试数据,输出数据编号以 及物体能够穿过垃圾管道并落下的最小宽度。输出的最小宽度并 向上舍入到最接近1/100倍数的数 ,你的答案与标准答案误差不能超过1/100。
    样例输入
    3
    0 0
    3 0
    0 4
    4
    0 10
    10 0
    20 10
    10 20
    0
    样例输出
    Case 1: 2.40
    Case 2: 14.15
    数据规模和约定
      30%的数据3<=n<=15
      100%的数据3<=n<=100
      0<=xi,yi<=10^4
      保证在一组数据中的所有的点互不不同,并且多边形的边不会相交(技术上,两条相邻的边不可避免的会有一个公共顶点,当然,这种情况我们不认为是相交)。
    ```

    ```c++
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;

    struct Point {
    double x, y;

    Point(double a = 0, double b = 0) : x(a), y(b) {}

    Point operator - (const Point &b) const {
    return Point(x - b.x, y - b.y);
    }

    bool operator < (const Point &b) const {
    return x < b.x || (x == b.x && y < b.y);
    }

    double norm(){//模的长度
    return sqrt(x * x + y * y);
    }
    };

    //计算a与b(向量积)的值
    double cross(Point a, Point b) {
    return a.x * b.y - a.y * b.x;
    }

    //判断b在a顺时针还是逆时针
    bool IsClockWise(Point p0, Point p1, Point p2) {
    if (cross(p1 - p0, p2 - p1) < 0)
    return true;
    else
    return false;
    }

    //安德鲁算法(Andrew’s Algorithm)求凸包
    int Andrew(Point *res, Point *p, int n) {
    sort(p, p+n);
    int m = 0; //凸包集合计数索引
    for (int i = 0; i < n; i++) { //从左向右扫描,创建凸包的上部
    while (m >= 2 && !IsClockWise(res[m-2], res[m-1], p[i]))
    m--;
    res[m++] = p[i];
    }
    int k = m;
    for (int i = n - 2; i >= 0; i--) { //从n-2开始是因为n-1一定在凸包的上部分,已包含,
    while (m > k && !IsClockWise(res[m-2], res[m-1], p[i]))
    m--;
    res[m++] = p[i];
    }
    if (m > 0) m--;
    return m;
    }

    //求点到边的距离
    double DistanceToLine(Point p, Point a, Point b) {
    double buttom = (a-b).norm();
    return fabs(cross(a-p, b-p)) / buttom;
    }

    int main() {
    Point res[105],p[105];
    int n;
    int cnt = 1;
    while (cin >> n && n) {
    for (int i = 0; i < n; i++)
    cin >> p[i].x >> p[i].y;
    int m = Andrew(res, p, n);
    double ans = INFINITY;
    //枚举每一条边作为低,求高的最小值。i取值从0~m,形成一个换
    for (int i = 0; i <= m; i++) {
    double max_high = 0.0;
    for (int j = 0; j < m; j++) {
    max_high = max(max_high, DistanceToLine(res[j], res[i], res[(i+1)%m]));
    }
    ans = min(ans,max_high);
    }
    ans = ceil(ans * 100) / 100;
    cout << "Case " << cnt++ << ": " << ans << endl;
    }
    return 0;
    }
    ```

  • 相关阅读:
    Net 下安装、调试的常见问题与错误
    解决在网页框架中,页面的样式表失效的方法
    C#.NET Show Text Info
    C#.NET 部署应用程序之ClickOnce
    VS2005 数据库间转移数据(SSIS)
    C#.NET ClickOnce
    SQL2005 还原备份数据
    C#.NET TreeView.cs
    C#.NET SetComboBox Class
    C#.NET GetLocalMachineInfo.cs
  • 原文地址:https://www.cnblogs.com/zhanyeye/p/10246592.html
Copyright © 2011-2022 走看看