【BZOJ1845】[Cqoi2005] 三角形面积并

Description

给出n个三角形,求它们并的面积。

Input

第一行为n(N < = 100), 即三角形的个数 以下n行,每行6个整数x1, y1, x2, y2, x3, y3,代表三角形的顶点坐标。坐标均为不超过10 ^ 6的实数,输入数据保留1位小数

Output

输出并的面积u, 保留两位小数

Sample Input

2
0.0 0.0 2.0 0.0 1.0 1.0
1.0 0.0 3.0 0.0 2.0 1.0

Sample Output

1.75

题解:先求出所有直线交点的x坐标(注意eps!),然后从左到右扫描每个区域。发现每个区域都可以看成若干个梯形,所以只需要用一条直线去截这些梯形的中间,得到所有梯形的中位线长乘上高度即为答案。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=110;
const double eps=1e-10;
double now,ans;
int n,m,tot,sum;
struct point
{
double x,y;
point(){}
point(double a,double b){x=a,y=b;}
point operator + (point a) {return point(x+a.x,y+a.y);}
point operator - (point a) {return point(x-a.x,y-a.y);}
double operator * (point a) {return x*a.y-y*a.x;}
point operator * (double a) {return point(x*a,y*a);}
point operator / (double a) {return point(x/a,y/a);}
};
struct line
{
point x,v;
line() {}
line(point a,point b){x=a,v=b;}
}s[310];
struct trangle
{
point a,b,c;
}t[110];
struct node
{
double x;
int v;
}q[210];
double p[100000];
bool cmp(node a,node b)
{
return a.x<b.x;
}
point getpoint(line a,line b)
{
point u=a.x-b.x;
double temp=(b.v*u)/(a.v*b.v);
return a.x+a.v*temp;
}
void calc(line a,line b)
{
if(fabs(a.v*b.v)<eps) return ;
point c=getpoint(a,b);
p[++m]=c.x;
}
int main()
{
scanf("%d",&n);
int i,j;
for(i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf%lf%lf",&t[i].a.x,&t[i].a.y,&t[i].b.x,&t[i].b.y,&t[i].c.x,&t[i].c.y);
if(t[i].a.x>t[i].b.x) swap(t[i].a,t[i].b);
if(t[i].a.x>t[i].c.x) swap(t[i].a,t[i].c);
if(t[i].b.x>t[i].c.x) swap(t[i].b,t[i].c);
s[i]=line(t[i].a,t[i].b-t[i].a),s[i+n]=line(t[i].a,t[i].c-t[i].a),s[i+n+n]=line(t[i].b,t[i].c-t[i].b);
}
for(i=1;i<=3*n;i++) for(j=i+1;j<=3*n;j++) calc(s[i],s[j]);
sort(p+1,p+m+1);
for(i=1;i<m;i++)
{
if(p[i+1]-p[i]<eps) continue;
now=(p[i]+p[i+1])/2;
for(tot=0,j=1;j<=n;j++)
{
if(now>=t[j].a.x&&now<=t[j].b.x)
{
q[++tot].x=t[j].a.y+(t[j].b.y-t[j].a.y)/(t[j].b.x-t[j].a.x)*(now-t[j].a.x);
q[++tot].x=t[j].a.y+(t[j].c.y-t[j].a.y)/(t[j].c.x-t[j].a.x)*(now-t[j].a.x);
if(q[tot].x<q[tot-1].x) swap(q[tot],q[tot-1]);
q[tot-1].v=1,q[tot].v=-1;
}
if(now>=t[j].b.x&&now<=t[j].c.x)
{
q[++tot].x=t[j].c.y+(t[j].b.y-t[j].c.y)/(t[j].c.x-t[j].b.x)*(t[j].c.x-now);
q[++tot].x=t[j].c.y+(t[j].a.y-t[j].c.y)/(t[j].c.x-t[j].a.x)*(t[j].c.x-now);
if(q[tot].x<q[tot-1].x) swap(q[tot],q[tot-1]);
q[tot-1].v=1,q[tot].v=-1;
}
}
sort(q+1,q+tot+1,cmp);
for(sum=0,j=1;j<=tot;j++)
{
if(sum) ans+=(p[i+1]-p[i])*(q[j].x-q[j-1].x);
sum+=q[j].v;
}
}
printf("%.2lf",ans-eps);
return 0;
}

【BZOJ1845】[Cqoi2005] 三角形面积并 几何+扫描线的更多相关文章

  1. BZOJ 1845: [Cqoi2005] 三角形面积并 [计算几何 扫描线]

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 1151  Solved: 313[Submit][Stat ...

  2. BZOJ1845 [Cqoi2005] 三角形面积并 扫描线 计算几何

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1845 题意概括 给出n个三角形,求其面积并. 题解 有一个很经典的扫描线题目:矩形面积并.那个比较 ...

  3. BZOJ1845 : [Cqoi2005] 三角形面积并

    求出所有交点后从左往右扫描线,用每段的中位线去截所有三角形,算出长度并后乘以该段长度即可,时间复杂度$O(n^3\log n)$. #include<cstdio> #include< ...

  4. bzoj 1845: [Cqoi2005] 三角形面积并 扫描线

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 848  Solved: 206[Submit][Statu ...

  5. CQOI2005 三角形面积并 和 POJ1177 Picture

    1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 1664  Solved: 443[Submit][Stat ...

  6. [CQOI2005]三角形面积并

    [CQOI2005]三角形面积并 题目大意: 求\(n(n\le100)\)个三角形的面积并. 思路: 自适应辛普森法,玄学卡精度可过. 源代码: #include<cmath> #inc ...

  7. BZOJ 1845: [Cqoi2005] 三角形面积并 (辛普森积分)

    大力辛普森积分 精度什么的搞了我好久- 学到了Simpson的一个trick 深度开11,eps开1e-4.跑的比有些扫描线还快- CODE #include <bits/stdc++.h> ...

  8. [hdu4629 Burning]三角形面积并,扫描线

    题意:给n个三角形,分别求覆盖1次~n次的总面积 思路: 对每个y坐标作一条平行于x轴的直线,按直线从下往上处理,每两条直线之间为若干梯形(也可以是三角形)首尾相连的情况,从左扫到右时,用一个变量cn ...

  9. ytu 1058: 三角形面积(带参的宏 练习)

    1058: 三角形面积 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 190  Solved: 128[Submit][Status][Web Boar ...

随机推荐

  1. 【Visual Studio】工程类型选择win32还是x64 ?

    1. 如果将Visual Studio的工程类型设置为win32,那么我们开发的程序既能在32位操作系统上运行,也能在64位操作系统上运行. 2. 如果将Visual Studio的工程类型设置为x6 ...

  2. 转 Python爬虫入门七之正则表达式

    静觅 » Python爬虫入门七之正则表达式 1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串 ...

  3. http协议相关面试题

    浏览器输入url按回车背后经历了哪些? 1.在PC浏览器的地址栏输入一串URL,然后按Enter键这个页面渲染出来,这个过程中都发生了什么事? 1.首先,在浏览器地址栏中输入url,先解析url,检测 ...

  4. kswapd0 进程 设置 swap

    kswapd0是虚拟内存管理中,负责换页,说白了就是你的物理内存不够用了 现在的服务器,一般内存都很高,所有很少使用 swap 分区了   这时候考虑的两种处理办法 加大物理内存 或者 增加swap分 ...

  5. python 之 线程池实现并发

    使用线程池实现高IO并发 模块:ThreadPoolExecutor, as_completed 测试代码如下: #!/opt/python3/bin/python3 from concurrent. ...

  6. Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)

    题目链接  Tree and Queries 题目大意  给出一棵树和每个节点的颜色.每次询问$vj, kj$ 你需要回答在以$vj$为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少 ...

  7. Vijos——P1137 组合数

    https://vijos.org/p/1137 描述 组合公式 C=N!/(M!*(N-M)!). 问题是求 C 中不同的质因子的个数例如 N=7, M=4. C=7!/(3!*4!)=5040/( ...

  8. Network | parity bit

    奇偶校验位是一个表示给定位数的二进制数中1的个数是奇数还是偶数的二进制数.奇偶校验位是最简单的错误检测码. A parity bit, or check bit is a bit added to t ...

  9. 老哥你真的知道ArrayList#sublist的正确用法么

    我们有这么一个场景,给你一个列表,可以动态的新增,但是最终要求列表升序,要求长度小于20,可以怎么做? 这个还不简单,几行代码就可以了 public List<Integer> trimL ...

  10. 12.Java web--过滤器与监听器

    1)过滤器 就是为请求与目标之间加一个或多个过滤器 自定义过滤器要实现Filter接口 下面是定义一个所有Servlet的请求中文不乱码 /** * 用于servlet输出中文乱码的过滤 */ @We ...