题意

题目描述

逆时针给出n个凸多边形的顶点坐标,求它们交的面积。例如n=2时,两个凸多边形如下图:

则相交部分的面积为5.233。

输入输出格式

输入格式:

第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形。第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标。

输出格式:

输出文件仅包含一个实数,表示相交部分的面积,保留三位小数。

输入输出样例

输入样例#1:
复制

2
6
-2 0
-1 -2
1 -2
2 0
1 2
-1 2
4
0 -3
1 -1
2 2
-1 0
输出样例#1:
复制

5.233

说明

100%的数据满足:2<=n<=10,3<=mi<=50,每维坐标为[-1000,1000]内的整数

分析

这题数据范围这么小,直接上半平面交模板即可。

点->左闭右开区间,半平面->闭区间。

操作顺序:

  1. 弹双端队列
  2. 加入队列
  3. 判平行
  4. 求交点

最后还要用第一个半平面去除无用的平面。当last-first<=1时,半平面交是空集

时间复杂度\(O(n\log n)\)

代码

注意空集的时候面积输出0仍然要保留三位小数。

算面积的写错了仍然能AC?

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
#define co const
using namespace std;

co double eps=1e-8;
int dcmp(double x) {return fabs(x)<eps?0:(x>0?1:-1);}
typedef struct Point{double x,y;}Vector;
Vector operator+(co Vector&u,co Vector&v) {return (Vector){u.x+v.x,u.y+v.y};}
Vector operator-(co Vector&u,co Vector&v) {return (Vector){u.x-v.x,u.y-v.y};}
Vector operator*(co Vector&u,double k) {return (Vector){u.x*k,u.y*k};}
double cross(co Vector&u,co Vector&v) {return u.x*v.y-u.y*v.x;}
double dot(co Vector&u,co Vector&v) {return u.x*v.x+u.y*v.y;}
struct Line{
    Point p;Vector v;
    double ang;
    bool operator<(co Line&l) {return ang<l.ang;}
};
bool left(co Line&l,co Point&p){
    return dcmp(cross(l.v,p-l.p))>0;
}
Point intersection(co Line&a,co Line&b){
    return a.p+a.v*(cross(b.v,a.p-b.p)/cross(a.v,b.v));
}

int main(){
    int n;scanf("%d",&n);
    vector<Line>ls;
    for(int m;n--;){
        scanf("%d",&m);
        static Point p[50];
        for(int i=0;i<m;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
        for(int i=0;i<m;++i) ls.push_back((Line){p[i],p[(i+1)%m]-p[i]});
    }
    for(int i=0;i<ls.size();++i) ls[i].ang=atan2(ls[i].v.y,ls[i].v.x);
    sort(ls.begin(),ls.end());
    vector<Point> p(ls.size());
    vector<Line> q(ls.size());
    int first,last;
    q[first=last=0]=ls[0];
    for(int i=1;i<ls.size();++i){
        while(first<last&&!left(ls[i],p[last-1])) --last;
        while(first<last&&!left(ls[i],p[first])) ++first;
        q[++last]=ls[i];
        if(dcmp(cross(q[last].v,q[last-1].v))==0){
            --last;
            if(left(q[last],ls[i].p)) q[last]=ls[i];
        }
        if(first<last) p[last-1]=intersection(q[last-1],q[last]);
    }
    while(first<last&&!left(q[first],p[last-1])) --last;
    if(last-first<=1) return puts("0.000"),0;
    p[last]=intersection(q[last],q[first]);
    vector<Point> ans;
    for(int i=first;i<=last;++i) ans.push_back(p[i]);
    double area=0;
    for(int i=1;i<ans.size();++i) area+=cross(ans[i]-ans[0],ans[(i+1)%ans.size()]-ans[0]);
    printf("%.3lf",fabs(area/2));
    return 0;
}

LG4196 [CQOI2006]凸多边形的更多相关文章

  1. 【BZOJ 2618】 2618: [Cqoi2006]凸多边形 (半平面交)

    2618: [Cqoi2006]凸多边形 Description 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. Input 第一 ...

  2. bzoj 2618 2618: [Cqoi2006]凸多边形(半平面交)

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 656  Solved: 340[Submit][Status] ...

  3. bzoj 2618: [Cqoi2006]凸多边形 [半平面交]

    2618: [Cqoi2006]凸多边形 半平面交 注意一开始多边形边界不要太大... #include <iostream> #include <cstdio> #inclu ...

  4. 【BZOJ2618】[CQOI2006]凸多边形(半平面交)

    [BZOJ2618][CQOI2006]凸多边形(半平面交) 题面 BZOJ 洛谷 题解 这个东西就是要求凸多边形的边所形成的半平面交. 那么就是一个半平面交模板题了. 这里写的是平方的做法. #in ...

  5. 2018.07.04 BZOJ 2618 Cqoi2006凸多边形(半平面交)

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec Memory Limit: 128 MB Description 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n ...

  6. 洛谷 P4196 [CQOI2006]凸多边形 (半平面交)

    题目链接:P4196 [CQOI2006]凸多边形 题意 给定 \(n\) 个凸多边形,求它们相交的面积. 思路 半平面交 半平面交的模板题. 代码 #include <bits/stdc++. ...

  7. bzoj2618: [Cqoi2006]凸多边形

    Description 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. Input 第一行有一个整数n,表示凸多边形的个数,以下依 ...

  8. BZOJ2618[Cqoi2006]凸多边形——半平面交

    题目描述 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. 输入 第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形.第 ...

  9. P4196 [CQOI2006]凸多边形 半平面交

    \(\color{#0066ff}{题目描述}\) 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. \(\color{#0066f ...

随机推荐

  1. Python Django 之 基于JQUERY的AJAX 登录页面

    一.基于Jquery的Ajax的实现 1.url 2.vews 3.templates

  2. RegDataToDataType

    function RegDataToDataType(Value: TRegDataType): Integer; begin case Value of rdString: Result := RE ...

  3. SpringBoot + Security实现权限控制

    网上找了好几个,因为各种原因不太行,下面这个亲测可行 参考:https://blog.csdn.net/u012702547/article/details/54319508 基于SpringBoot ...

  4. UI控件Telerik UI for WinForms发布R1 2019|附下载

    Telerik UI for WinForms拥有适用Windows Forms的110多个令人惊叹的UI控件.所有的UI for WinForms控件都具有完整的主题支持,可以轻松地帮助开发人员在桌 ...

  5. linux 清空文件

    将Linux文件清空的几种方法 1.使用重定向的方法 [root@centos7 ~]# du -h test.txt 4.0K test.txt [root@centos7 ~]# > tes ...

  6. Final阶段第1周/共1周 Scrum立会报告+燃尽图 05

    作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2484] 版本控制:https://git.coding.net/liuyy08 ...

  7. L271 操纵太空中航天器的几种方法

    Manoeuvring a satellite in orbit usually requires thrusters. Sometimes the thrust is provided by a f ...

  8. rem问题

    rem为单位时,根元素html的font-size 必须>=12px,否则 默认为font-size:12px. 为啥 html 设置成 62.5%,或者 10px 时,这种换算无效了呢?经过研 ...

  9. phpcms 操作数据库 增删改查

    数据库的其他类继承的都是libs/class/model.class.php 这里面有写好的操作数据库的常用方法 1.增 insert($data, $return_insert_id = false ...

  10. Spring Boot 揭秘与实战(七) 实用技术篇 - StateMachine 状态机机制

    文章目录 1. 环境依赖 2. 状态和事件 2.1. 状态枚举 2.2. 事件枚举 3. 状态机配置4. 状态监听器 3.1. 初始化状态机状态 3.2. 初始化状态迁移事件 5. 总结 6. 源代码 ...