Gym 100952J&&2015 HIAST Collegiate Programming Contest J. Polygons Intersection【计算几何求解两个凸多边形的相交面积板子题】
J. Polygons Intersection
We will not waste your time, it is a straightforward problem. Given multiple polygons, calculate the area of their intersection. For simplicity, there will be exactly 2 polygons both of them are convex, given in the counterclockwise order and have non-zero areas. Furthermore, in one polygon a vertex won't be on the sides of the other one. The figure below demonstrates the first test case.
The first line of the input will be a single integer T, the number of test cases (1 ≤ T ≤ 20). each test case contains two integers (3 ≤ N, M ≤ 40) Then a line contains N pairs of integers xi, yi (-1000 ≤ xi, yi ≤ 1000) coordinates of the ith vertex of polygon A, followed by a line contains M pairs of integers xj, yj (-1000 ≤ xj, yj ≤ 1000) coordinates of the jth vertex of polygon B. The coordinates are separated by a single space.
For each test case, print on a single line, a single number representing the area of intersection, rounded to four decimal places.
- 2
5 3
0 3 1 1 3 1 3 5 1 5
1 3 5 3 3 6
3 3
-1 -1 -2 -1 -1 -2
1 1 2 1 1 2
- 2.6667
0.0000
题目链接:http://codeforces.com/gym/100952/problem/J
题意:给2个凸多边形,求相交面积
思路:板子题,学习一下!
下面给出AC代码:
- #include "iostream"
- #include "string.h"
- #include "stack"
- #include "queue"
- #include "string"
- #include "vector"
- #include "set"
- #include "map"
- #include "algorithm"
- #include "stdio.h"
- #include "math.h"
- #define ll long long
- #define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
- #define mem(a) memset(a,0,sizeof(a))
- #define mp(x,y) make_pair(x,y)
- using namespace std;
- const long long INF = 1e18+1LL;
- const int inf = 1e9+1e8;
- const int N=1e5+;
- #define maxn 510
- const double eps=1E-;
- int sig(double d){
- return(d>eps)-(d<-eps);
- }
- struct Point{
- double x,y; Point(){}
- Point(double x,double y):x(x),y(y){}
- bool operator==(const Point&p)const{
- return sig(x-p.x)==&&sig(y-p.y)==;
- }
- };
- double cross(Point o,Point a,Point b){
- return(a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
- }
- double area(Point* ps,int n){
- ps[n]=ps[];
- double res=;
- for(int i=;i<n;i++){
- res+=ps[i].x*ps[i+].y-ps[i].y*ps[i+].x;
- }
- return res/2.0;
- }
- int lineCross(Point a,Point b,Point c,Point d,Point&p){
- double s1,s2;
- s1=cross(a,b,c);
- s2=cross(a,b,d);
- if(sig(s1)==&&sig(s2)==) return ;
- if(sig(s2-s1)==) return ;
- p.x=(c.x*s2-d.x*s1)/(s2-s1);
- p.y=(c.y*s2-d.y*s1)/(s2-s1);
- return ;
- }
- //多边形切割
- //用直线ab切割多边形p,切割后的在向量(a,b)的左侧,并原地保存切割结果
- //如果退化为一个点,也会返回去,此时n为1
- void polygon_cut(Point*p,int&n,Point a,Point b){
- static Point pp[maxn];
- int m=;p[n]=p[];
- for(int i=;i<n;i++){
- if(sig(cross(a,b,p[i]))>) pp[m++]=p[i];
- if(sig(cross(a,b,p[i]))!=sig(cross(a,b,p[i+])))
- lineCross(a,b,p[i],p[i+],pp[m++]);
- }
- n=;
- for(int i=;i<m;i++)
- if(!i||!(pp[i]==pp[i-]))
- p[n++]=pp[i];
- while(n>&&p[n-]==p[])n--;
- }
- //---------------华丽的分隔线-----------------//
- //返回三角形oab和三角形ocd的有向交面积,o是原点//
- double intersectArea(Point a,Point b,Point c,Point d){
- Point o(,);
- int s1=sig(cross(o,a,b));
- int s2=sig(cross(o,c,d));
- if(s1==||s2==)return 0.0;//退化,面积为0
- if(s1==-) swap(a,b);
- if(s2==-) swap(c,d);
- Point p[]={o,a,b};
- int n=;
- polygon_cut(p,n,o,c);
- polygon_cut(p,n,c,d);
- polygon_cut(p,n,d,o);
- double res=fabs(area(p,n));
- if(s1*s2==-) res=-res;return res;
- }
- //求两多边形的交面积
- double intersectArea(Point*ps1,int n1,Point*ps2,int n2){
- if(area(ps1,n1)<) reverse(ps1,ps1+n1);
- if(area(ps2,n2)<) reverse(ps2,ps2+n2);
- ps1[n1]=ps1[];
- ps2[n2]=ps2[];
- double res=;
- for(int i=;i<n1;i++){
- for(int j=;j<n2;j++){
- res+=intersectArea(ps1[i],ps1[i+],ps2[j],ps2[j+]);
- }
- }
- return res;//assumeresispositive!
- }
- //hdu-3060求两个任意简单多边形的并面积
- Point ps1[maxn],ps2[maxn];
- int n1,n2;
- int main(){
- int t;
- cin>>t;
- while(t--){
- scanf("%d%d",&n1,&n2);
- for(int i=;i<n1;i++)
- scanf("%lf%lf",&ps1[i].x,&ps1[i].y);
- for(int i=;i<n2;i++)
- scanf("%lf%lf",&ps2[i].x,&ps2[i].y);
- double ans=intersectArea(ps1,n1,ps2,n2);
- //ans=fabs(area(ps1,n1))+fabs(area(ps2,n2))-ans;//容斥
- printf("%.4f\n",ans);
- }
- return ;
- }
Gym 100952J&&2015 HIAST Collegiate Programming Contest J. Polygons Intersection【计算几何求解两个凸多边形的相交面积板子题】的更多相关文章
- Gym 100952E&&2015 HIAST Collegiate Programming Contest E. Arrange Teams【DFS+剪枝】
E. Arrange Teams time limit per test:2 seconds memory limit per test:64 megabytes input:standard inp ...
- Gym 100952F&&2015 HIAST Collegiate Programming Contest F. Contestants Ranking【BFS+STL乱搞(map+vector)+优先队列】
F. Contestants Ranking time limit per test:1 second memory limit per test:24 megabytes input:standar ...
- Gym 100952A&&2015 HIAST Collegiate Programming Contest A. Who is the winner?【字符串,暴力】
A. Who is the winner? time limit per test:1 second memory limit per test:64 megabytes input:standard ...
- Gym 100952I&&2015 HIAST Collegiate Programming Contest I. Mancala【模拟】
I. Mancala time limit per test:3 seconds memory limit per test:256 megabytes input:standard input ou ...
- Gym 100952H&&2015 HIAST Collegiate Programming Contest H. Special Palindrome【dp预处理+矩阵快速幂/打表解法】
H. Special Palindrome time limit per test:1 second memory limit per test:64 megabytes input:standard ...
- Gym 100952D&&2015 HIAST Collegiate Programming Contest D. Time to go back【杨辉三角预处理,组合数,dp】
D. Time to go back time limit per test:1 second memory limit per test:256 megabytes input:standard i ...
- Gym 100952C&&2015 HIAST Collegiate Programming Contest C. Palindrome Again !!【字符串,模拟】
C. Palindrome Again !! time limit per test:1 second memory limit per test:64 megabytes input:standar ...
- Gym 100952G&&2015 HIAST Collegiate Programming Contest G. The jar of divisors【简单博弈】
G. The jar of divisors time limit per test:2 seconds memory limit per test:64 megabytes input:standa ...
- Gym 100952B&&2015 HIAST Collegiate Programming Contest B. New Job【模拟】
B. New Job time limit per test:1 second memory limit per test:64 megabytes input:standard input outp ...
随机推荐
- Oracle索引详解
Oracle索引详解(二) --索引分类 Oracle 提供了大量索引选项.知道在给定条件下使用哪个选项对于一个程序的性能来说非常重要.一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程 ...
- HTML5 桌面通知:Notification API
原文地址:http://blog.gdfengshuo.com/article/23/ 前言 Notification API 是 HTML5 新增的桌面通知 API,用于向用户显示通知信息.该通知是 ...
- verilog抓外部低频输入信号的上升沿和下降沿
版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7220107.html 作者:窗户 Q ...
- ORACLE环境变量设置
用oracle帐号登录,配置相关环境变量: vi .bash_profile export ORACLE_BASE=/u01/app/oracleexport ORACLE_HOME=/u01/app ...
- 浏览器根对象window之screen
1. screen 1.1 availHeight/Width screen.availWidth返回浏览器窗口可占用的水平宽度(单位:像素). screen.availHeight返回浏览器窗口在屏 ...
- I/O模型详细解析
内核空间和用户空间:由于操作系统都包括内核空间和用户空间(或者说内核态和用户态),内核空间主要存放的是内核代码和数据,是供系统进程使用的空间.而用户空间主要存放的是用户代码和数据,是供用户进程使用的空 ...
- 转深入理解 AngularJS 的 Scope作用域
文章转载英文:what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs 中文:http://www. ...
- (5编译使用最新opencv)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练 1综述http://www.cnblogs.com/jsxyhelu/p/7907241.html 2环境架设http://www.c ...
- gitignore样例解析
# 这是注释行 -- 被忽略 *.a # 忽略所有以 .a 为扩展名的文件 !lib.a # 但是lib.a 文件或目录不要忽略,即使前面设置了对*.a的忽略 /TODO # 只忽略此目录下的TODO ...
- 《深入解剖Yii2框架》前言
写代码需要站在巨人的肩膀上,将主要精力集中在自己所需要实现的业务上面,避免反复搭建基础服务,重复造轮子.PHP框架就是这样一些巨人的"肩膀",使得我们"站"得更 ...