Uva 10652 Board Wrapping

二次联通门 : Virtual Judge Uva 10652 Board Wrapping

/*
    Uva 10652 Board Wrapping

    计算几何

    将每个家具拆为4个点

    对所有点求一个凸包
    然后求凸包的面积即可 

    思路不难。。
    但是写起来好麻烦好麻烦

    需要注意的东西有很多

    1. 角度制转弧度制
     2. EPS的选择
    3. PI的取值 (以防万一以后还是都写acos(-1)吧。。。)
    4. 在把家具拆成四个点时的细节
    4. 计算多边形的面积
*/
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>

#define Max 2500

#define PI 3.1415926535897

#define EPS 1e-8

void read (int &now)
{
    register char word = getchar ();
    for (now = 0; !isdigit (word); word = getchar ());
    for (; isdigit (word); now = now * 10 + word - ‘0‘, word = getchar ());
}

struct Point
{
    double x, y;

    Point (const double &__x, const double &__y) : x (__x), y (__y) {}
    Point () {}

    bool operator < (const Point &now) const
    {
        return this->x == now.x ? this->y < now.y : this->x < now.x;
    }

    bool operator == (const Point &now) const
    {
        return (this->x - now.x < EPS) && (this->y - now.y < EPS);
    }
};
typedef Point Vector;

Vector operator + (const Vector &A, const Vector &B)
{
    return Vector (A.x + B.x, A.y + B.y);
}

Vector operator - (const Vector &A, const Vector &B)
{
    return Vector (A.x - B.x, A.y - B.y);
}

Vector operator * (const Vector &now, const double P)
{
    return Vector (now.x * P, now.y * P);
}

Vector operator / (const Vector &now, const double P)
{
    return Vector (now.x / P, now.y / P);
}

inline double to_rad (double now)
{
    return now / 180 * PI;
}

inline Vector Rotate (Vector A, double rad)
{
    return Vector (A.x * cos (rad) - A.y * sin (rad), A.x * sin (rad) + A.y * cos (rad));
}

inline double Cross (Vector A, Vector B)
{
    return A.x * B.y - A.y * B.x;
}

int Convex_Hull (Point *point, int N, Point *Stack)
{
    std :: sort (point, point + N);
    int top = 0;
    for (int i = 0; i < N; i ++)
    {
        for (; top > 1 && Cross (Stack[top - 1] - Stack[top - 2], point[i] - Stack[top - 2]) <= 0; -- top);
        Stack[top ++] = point[i];
    }

    int k = top;
    for (int i = N - 2; i >= 0; -- i)
    {
        for (; top > k && Cross (Stack[top - 1] - Stack[top - 2], point[i] - Stack[top - 2]) <= 0; -- top);
        Stack[top ++] = point[i];
    }
    if (N > 1)
        -- top;
    return top;

}

double Polygon_Area (Point *point, int N)
{
    double area = 0;
    for (int i = 1; i < N - 1; i ++)
        area += Cross (point[i] - point[0], point[i + 1] - point[0]);
    return area / 2;
}

Point point[Max], Stack[Max];

int main (int argc, char *argv[])
{
    int T, N, M;

    read (T);
    register int i;
    double x, y, w, h, j;
    double angle, _area;

    int cur;
    for (; T; -- T)
    {
        read (N);
        cur = 0, _area = 0;
        for (i = 1; i <= N; ++ i)
        {
            scanf ("%lf%lf%lf%lf%lf", &x, &y, &w, &h, &j);
            Point now (x, y);

            angle = -to_rad (j);
            point[cur ++] = now + Rotate (Vector (-w / 2, -h / 2), angle);
            point[cur ++] = now + Rotate (Vector (w / 2, -h / 2), angle);
            point[cur ++] = now + Rotate (Vector (-w / 2, h / 2), angle);
            point[cur ++] = now + Rotate (Vector (w / 2, h / 2), angle);

            _area += w * h;
        }

        M = Convex_Hull (point, cur, Stack);
        double __area = Polygon_Area (Stack, M);

        printf ("%.1lf %%\n", _area * 100 / __area);
    }
    return 0;
}
时间: 2024-12-10 20:15:23

Uva 10652 Board Wrapping的相关文章

uva 10652 Board Wrapping (计算几何-凸包)

Problem B Board Wrapping Input: standard input Output: standard output Time Limit: 2 seconds The small sawmill in Mission, British Columbia, has developed a brand new way of packaging boards for drying. By fixating the boards in special moulds, the b

UVA 10652 Board Wrapping 计算几何

多边形凸包.... Board Wrapping Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem B Board Wrapping Input: standard input Output: standard output Time Limit: 2 seconds The small sawmill in Mission, Britis

UVA 10652 Board Wrapping(凸包)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32286 [思路] 凸包 根据角度与中心点求出长方形所有点来,然后就可以应用凸包算法了. [代码] #include<cmath> #include<cstdio> #include<algorithm> using namespace std; const double PI = acos(-1.0); double torad(doub

Uva - 10652 Board Wrapping(凸包)

给定一些长方形的坐标,求长方形的面积与围住这些长方形面积的凸包的百分比. 首先假设长方形都是水平放置,那么根据长和宽还有中心坐标,可以求出四个顶点的坐标,然后求出从中心指向顶点的向量,和角度转化成的弧度,向量旋转之后得到一个新的向量 是由中心指向新的顶点,加上中心点就得到新的顶点的坐标.可以画图理解. 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm&

UVA 10652 Board Wrapping(二维凸包)

传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组先输入木板个数n,接下来n行,每行x,y,w,h,j.(x,y)是木板中心的坐标,w是宽,h是高,j是顺时针旋转的角度. 木板互不相交. 输出:对于每组数据,输出木板总面积占包装总面积的百分比,保留小数点后1位. 题解:典型的二维凸包问题,理解并调用模板即可. #include <math.h>

简单几何(向量旋转+凸包+多边形面积) UVA 10652 Board Wrapping

题目传送门 题意:告诉若干个矩形的信息,问他们在凸多边形中所占的面积比例 分析:训练指南P272,矩形面积长*宽,只要计算出所有的点,用凸包后再求多边形面积.已知矩形的中心,向量在原点参考点再旋转,角度要转换成弧度制. /************************************************ * Author :Running_Time * Created Time :2015/11/10 星期二 10:34:43 * File Name :UVA_10652.cpp

UVA 10652 Board Wrapping(计算几何基础,求凸包)

题目链接:传送门 分析: 没有什么好说的就是求一个凸包就好了.可以当作模板. 代码如下: #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const double eps = 1e-10; //判断符号,提高精度 int dcmp(double x){ if(fab

Board Wrapping(计算几何求凸包加向量的旋转)

UVA - 10652 Board Wrapping Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description Problem B Board Wrapping Input: standard input Output: standard output Time Limit: 2 seconds The small sa

UVa 10652 (简单凸包) Board Wrapping

题意: 有n块互不重叠的矩形木板,用尽量小的凸多边形将它们包起来,并输出并输出木板总面积占凸多边形面积的百分比. 分析: 几乎是凸包和多边形面积的裸题. 注意:最后输出的百分号前面有个空格,第一次交PE了. 用printf打印%,可以连续打印两个%%,printf("%%\n");   这个冷知识记得以前学过,不过不用也就忘了. 学习一下vector容器中去重的小技巧. sort(p.begin(), p.end()); p.erase(unique(p.begin(), p.end(