HDU 3060 多边形面积并

Area2

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1197    Accepted Submission(s): 278

Problem Description

小白近期又被空军特招为飞行员,參与一项实战演习。演习的内容还是轰炸某个岛屿(这次的岛屿非常大,非常大非常大非常大,大到炸弹怎么扔都能全然在岛屿上引爆),看来小白确实是飞行员的命。。。

这一次,小白扔的炸弹比較奇怪,爆炸的覆盖区域不是圆形,而是一个不规则的简单多边形,请你再次帮助小白,计算出炸到了多少面积。

须要注意的是,这次小白一共扔了两枚炸弹,可是两枚炸弹炸到的公共部分的面积仅仅能计算一次。

Input

首先输入两个数n,m,分别代表两枚炸弹爆炸覆盖到的图形的顶点数;

接着输入n行,每行输入一个(x,y)坐标,代表第一枚炸弹爆炸范围图形的顶点(按顺势针或者逆时针给出)。

最后输入m行,每行输入一个(x‘,y‘)坐标,代表第二枚炸弹爆炸范围图形的顶点(按顺势针或者逆时针给出)。

(3<= n,m <= 500)

Output

输出一个两位小数,表示实际轰炸到的岛屿的面积。

Sample Input

4 4
0 0
0 1
1 1
1 0
0.5 0.5
0.5 1.5
1.5 1.5
1.5 0.5

Sample Output

1.75

给定两个多边形,求面积并

把多边形分解成三角形,然后计算三角形的有向面积交。

代码:

/* ***********************************************
Author :_rabbit
Created Time :2014/5/4 15:03:55
File Name :20.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 10000000
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
int dcmp(double x){
    if(fabs(x)<eps)return 0;
    return x>0?1:-1;
}
struct Point{
    double x,y;
    Point(double _x=0,double _y=0){
        x=_x;y=_y;
    }
};
Point operator + (const Point &a,const Point &b){
    return Point(a.x+b.x,a.y+b.y);
}
Point operator - (const Point &a,const Point &b){
    return Point(a.x-b.x,a.y-b.y);
}
Point operator * (const Point &a,const double &p){
    return Point(a.x*p,a.y*p);
}
Point operator / (const Point &a,const double &p){
    return Point(a.x/p,a.y/p);
}
bool operator < (const Point &a,const Point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
bool operator == (const Point &a,const Point &b){
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(Point  a,Point b){
    return a.x*b.x+a.y*b.y;
}
double Length(Point a){
    return sqrt(Dot(a,a));
}
double Angle(Point a,Point b){
    return acos(Dot(a,b)/Length(a)/Length(b));
}
double angle(Point a){
    return atan2(a.y,a.x);
}
double Cross(Point a,Point b){
    return a.x*b.y-a.y*b.x;
}
Point vecunit(Point a){
    return a/Length(a);
}
Point Normal(Point a){
    return Point(-a.y,a.x)/Length(a);
}
Point Rotate(Point a,double rad){
    return Point(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}
double Area2(Point a,Point b,Point c){
    return Length(Cross(b-a,c-a));
}
struct Line{
    Point p,v;
    double ang;
    Line(){};
    Line(Point p,Point v):p(p),v(v){
        ang=atan2(v.y,v.x);
    }
    bool operator < (const Line &L) const {
        return ang<L.ang;
    }
};
bool OnLeft(const Line &L,const Point &p){
    return dcmp(Cross(L.v,p-L.p))>=0;
}
Point GetLineIntersection(Point p,Point v,Point q,Point w){
    Point u=p-q;
    double t=Cross(w,u)/Cross(v,w);
    return p+v*t;
}
Point GetLineIntersection(Line a,Line b){
    return GetLineIntersection(a.p,a.v,b.p,b.v);
}
vector<Point> HPI(vector<Line> L){
    int n=L.size();
    sort(L.begin(),L.end());//将全部半平面依照极角排序。
    int first,last;
    vector<Point> p(n);
    vector<Line> q(n);
    vector<Point> ans;
    q[first=last=0]=L[0];
    for(int i=1;i<n;i++){
        while(first<last&&!OnLeft(L[i],p[last-1]))last--;//删除顶部的半平面
        while(first<last&&!OnLeft(L[i],p[first]))first++;//删除底部的半平面
        q[++last]=L[i];//将当前的半平面假如双端队列顶部。
        if(fabs(Cross(q[last].v,q[last-1].v))<eps){//对于极角同样的,选择性保留一个。
            last--;
            if(OnLeft(q[last],L[i].p))q[last]=L[i];
        }
        if(first<last)p[last-1]=GetLineIntersection(q[last-1],q[last]);//计算队列顶部半平面交点。
    }
    while(first<last&&!OnLeft(q[first],p[last-1]))last--;//删除队列顶部的无用半平面。
    //cout<<first<<" "<<last<<endl;
    if(last-first<=1)return ans;//半平面退化
    p[last]=GetLineIntersection(q[last],q[first]);//计算队列顶部与首部的交点。
    for(int i=first;i<=last;i++)ans.push_back(p[i]);//将队列中的点复制。
    return ans;
}
double PolyArea(vector<Point> p){
    int n=p.size();
    double ans=0;
    for(int i=1;i<n-1;i++)
        ans+=Cross(p[i]-p[0],p[i+1]-p[0]);
    return ans/2;
}
vector<Point> p1,p2;
int main()
{
     //freopen("data.in","r",stdin);
     //freopen("data.out","w",stdout);
     int n,m;
     while(~scanf("%d%d",&n,&m)){
         Point pp;
		 p1.clear();p2.clear();
         for(int i=0;i<n;i++)scanf("%lf%lf",&pp.x,&pp.y),p1.push_back(pp);
         for(int i=0;i<m;i++)scanf("%lf%lf",&pp.x,&pp.y),p2.push_back(pp);
         double ret1,ret2,ret=0;
         ret1=PolyArea(p1);if(dcmp(ret1)<0)reverse(p1.begin(),p1.end());ret+=fabs(ret1);
         ret2=PolyArea(p2);if(dcmp(ret2)<0)reverse(p2.begin(),p2.end());ret+=fabs(ret2);
         for(int i=1;i<n-1;i++)
             for(int j=1;j<m-1;j++){
                 vector<Point> s1,s2;
                 s1.push_back(p1[0]);
                 s1.push_back(p1[i]);
                 s1.push_back(p1[i+1]);
                 s2.push_back(p2[0]);
                 s2.push_back(p2[j]);
                 s2.push_back(p2[j+1]);
                 double r1,r2;
                 int flag1,flag2;
                 r1=PolyArea(s1);
                 if(dcmp(r1)>=0)flag1=1;else flag1=0;
                 if(dcmp(r1)<0)reverse(s1.begin(),s1.end());
                 r2=PolyArea(s2);
                 if(dcmp(r2)>=0)flag2=1;else flag2=0;
                 if(dcmp(r2)<0)reverse(s2.begin(),s2.end());
                 vector<Line> L;
                 for(int k=0;k<3;k++)
                     L.push_back(Line(s1[k],s1[(k+1)%3]-s1[k]));
                 for(int k=0;k<3;k++)
                     L.push_back(Line(s2[k],s2[(k+1)%3]-s2[k]));
                 vector<Point> tt=HPI(L);
                 if(flag1==flag2)ret-=PolyArea(tt);
                 else ret+=PolyArea(tt);
             }
         printf("%.2lf\n",ret);
     }
     return 0;
}

HDU 3060 多边形面积并,布布扣,bubuko.com

时间: 2024-10-13 16:15:23

HDU 3060 多边形面积并的相关文章

HDU 3982 半平面交+圆与多边形面积交

Harry Potter and J.K.Rowling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 685    Accepted Submission(s): 210 Problem Description In July 31st, last month, the author of the famous novel seri

hdu 2892 多边形与园面积相交

area Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 623    Accepted Submission(s): 233 Problem Description 小白最近被空军特招为飞行员,参与一项实战演习.演习的内容是轰炸某个岛屿... 作为一名优秀的飞行员,任务是必须要完成的,当然,凭借小白出色的操作,顺利地将炸弹投到了岛上某

hdu 2034 改革春风吹满地 多边形面积

改革春风吹满地 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Description “ 改革春风吹满地,不会AC没关系;实在不行回老家,还有一亩三分地.谢谢!(乐队奏乐)” 话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里雾里,而且,还竟然来这么几句打油诗.好呀,老师的责任就是帮你解决问题,既然想种田,那就分你一块.这块田位于浙江省温州

HDU 2036 改革春风吹满地 (求多边形面积)

传送门: 改革春风吹满地 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 42663    Accepted Submission(s): 21856 Problem Description " 改革春风吹满地,不会AC没关系;实在不行回老家,还有一亩三分地.谢谢!(乐队奏乐)" 话说部分学生心态极好,每天就知道游戏,这次考试如

hdu 2036 求多边形面积 (凸、凹多边形)

<题目链接> Problem Description " 改革春风吹满地,不会AC没关系;实在不行回老家,还有一亩三分地.谢谢!(乐队奏乐)" 话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里雾里,而且,还竟然来这么几句打油诗.好呀,老师的责任就是帮你解决问题,既然想种田,那就分你一块.这块田位于浙江省温州市苍南县灵溪镇林家铺子村,多边形形状的一块地,原本是linle 的,现在就准备送给你了.不过,任何事情都没有那么简单,你必须首先告诉我这块地到底有多

多边形面积模板

HDU 2036 改革春风吹满地 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 20033    Accepted Submission(s): 10256 Problem Description “ 改革春风吹满地, 不会AC没关系; 实在不行回老家, 还有一亩三分地. 谢谢!(乐队奏乐)”话说部分学生心态极好,每天就知道游戏,这次

ecnu1624求交集多边形面积

链接 本来在刷hdu的一道题..一直没过,看到谈论区发现有凹的,我这种方法只能过凸多边形的相交面积.. 就找来这道题试下水. 两个凸多边形相交的部分要么没有 要么也是凸多边形,那就可以把这部分单独拿出来极角排序.叉积求面积.这部分的顶点要么p在q内的顶点,要么是q在p内的顶点,要么是两凸多边形的交点. 用到了点在多边形内的判定模板. 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #inclu

改革春风吹满地(多边形面积)

http://acm.hdu.edu.cn/showproblem.php?pid=2036 改革春风吹满地 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 22973    Accepted Submission(s): 11889 Problem Description “ 改革春风吹满地,不会AC没关系;实在不行回老家,还有一亩三分

多边形面积公式

多边形面积公式 设点顺序 (x1 y1) (x2 y2)    ... (xn yn) 则面积等于 |x1   y1 |      |x2   y2|                  |xn   yn| 0.5 * abs( |            | +   |           | + ...... +   |           | ) |x2   y2 |      |x3   y3|                  |x1   y1| 其中        |x1   y1| |