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

题目传送门

题意:告诉若干个矩形的信息,问他们在凸多边形中所占的面积比例

分析:训练指南P272,矩形面积长*宽,只要计算出所有的点,用凸包后再求多边形面积。已知矩形的中心,向量在原点参考点再旋转,角度要转换成弧度制。

/************************************************
* Author        :Running_Time
* Created Time  :2015/11/10 星期二 10:34:43
* File Name     :UVA_10652.cpp
 ************************************************/

#include <bits/stdc++.h>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-10;
const double PI = acos (-1.0);
int dcmp(double x)  {
    if (fabs (x) < EPS) return 0;
    else    return x < 0 ? -1 : 1;
}
struct Point    {
    double x, y;
    Point () {}
    Point (double x, double y) : x (x), y (y) {}
    Point operator - (const Point &r) const {       //向量减法
        return Point (x - r.x, y - r.y);
    }
    Point operator * (double p) const {       //向量乘以标量
        return Point (x * p, y * p);
    }
    Point operator / (double p) const {       //向量除以标量
        return Point (x / p, y / p);
    }
    Point operator + (const Point &r) const {
        return Point (x + r.x, y + r.y);
    }
    bool operator < (const Point &r) const {
        return x < r.x || (x == r.x && y < r.y);
    }
    bool operator == (const Point &r) const {
        return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
    }
};
typedef Point Vector;
double dot(Vector A, Vector B)  {       //向量点积
    return A.x * B.x + A.y * B.y;
}
double cross(Vector A, Vector B)    {       //向量叉积
    return A.x * B.y - A.y * B.x;
}
Vector rotate(Vector A, double rad)   {
    return Vector (A.x * cos (rad) - A.y * sin (rad), A.x * sin (rad) + A.y * cos (rad));
}
double area_poly(vector<Point> ps)  {
    double ret = 0;
    for (int i=1; i<ps.size ()-1; ++i)  {
        ret += fabs (cross (ps[i] - ps[0], ps[i+1] - ps[0])) / 2;
    }
    return ret;
}
vector<Point> convex_hull(vector<Point> ps) {
    sort (ps.begin (), ps.end ());
    ps.erase (unique (ps.begin (), ps.end ()), ps.end ());
    int n = ps.size (), k = 0;
    vector<Point> qs (n * 2);
    for (int i=0; i<n; ++i) {
        while (k > 1 && cross (qs[k-1] - qs[k-2], ps[i] - qs[k-2]) <= 0)    k--;
        qs[k++] = ps[i];
    }
    for (int t=k, i=n-2; i>=0; --i) {
        while (k > t && cross (qs[k-1] - qs[k-2], ps[i] - qs[k-2]) <= 0)    k--;
        qs[k++] = ps[i];
    }
    qs.resize (k - 1);
    return qs;
}

int main(void)    {
    int T;  scanf ("%d", &T);
    while (T--) {
        int n;  scanf ("%d", &n);
        vector<Point> ps;
        double area1 = 0;
        double x, y, w, h, r;
        for (int i=0; i<n; ++i) {
            scanf ("%lf%lf%lf%lf%lf", &x, &y, &w, &h, &r);
            Point a = Point (x, y);
            area1 += w * h;
            r = -r / 180 * PI;
            ps.push_back (a + rotate (Vector (-w/2, -h/2), r));
            ps.push_back (a + rotate (Vector (w/2, -h/2), r));
            ps.push_back (a + rotate (Vector (w/2, h/2), r));
            ps.push_back (a + rotate (Vector (-w/2, h/2), r));
        }
        vector<Point> qs = convex_hull (ps);
        printf ("%.1f %%\n", 100 * area1 / area_poly (qs));
    }

   //cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";

    return 0;
}

  

时间: 2024-10-16 12:10:10

简单几何(向量旋转+凸包+多边形面积) 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

二次联通门 : Virtual Judge Uva 10652 Board Wrapping /* Uva 10652 Board Wrapping 计算几何 将每个家具拆为4个点 对所有点求一个凸包 然后求凸包的面积即可 思路不难.. 但是写起来好麻烦好麻烦 需要注意的东西有很多 1. 角度制转弧度制 2. EPS的选择 3. PI的取值 (以防万一以后还是都写acos(-1)吧...) 4. 在把家具拆成四个点时的细节 4. 计算多边形的面积 */ #include <algorithm>

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(凸包)

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

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(计算几何基础,求凸包)

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

UVA 10652 Board Wrapping(二维凸包)

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

HDU 1700 Points on Cycle (几何 向量旋转)

http://acm.hdu.edu.cn/showproblem.php?pid=1700 题目大意: 二维平面,一个圆的圆心在原点上.给定圆上的一点A,求另外两点B,C,B.C在圆上,并且三角形ABC的周长是最长的. 解题思路: 我记得小学的时候给出个一个定理,在园里面正多边形的的周长是最长的,这个定理我不会证明. 所以这里是三角形,当三角形为正三角形的时候,周长是最长的. 因为圆心在原点,所以我就向量(x,y)绕原点逆时针旋转120度和顺时针旋转120度.给定的点A可以看成(x,y)向量.

简单几何(凸包+多边形面积) POJ 3348 Cows

题目传送门 题意:求凸包 + (int)求面积 / 50 /************************************************ * Author :Running_Time * Created Time :2015/11/4 星期三 11:13:29 * File Name :POJ_3348.cpp ************************************************/ #include <cstdio> #include <a