1845: [Cqoi2005] 三角形面积并

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 848  Solved: 206
[Submit][Status][Discuss]

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
 
  以前一直听说有一个除辛普森积分外的求面积的方法,现在才终于编了一次,大概思路就是通过扫描线,将答案转换成一个一个梯形相加。
  另:unique的函数参数应该传进去等于符号的比较函数,而不是大于符号,每次都会搞错。。
 
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
#define MAXN 1000
#define sqr(x) ((x)*(x))
#define eps 1e-10
typedef double real;
inline int sgn(real x)
{
if (abs(x)<eps)
return ;
return x<?-:;
}
struct point
{
real x,y;
point(real x,real y):x(x),y(y){}
point(){}
void read()
{
scanf("%lf%lf",&x,&y);
}
};
real dis(point p1,point p2)
{
return sqrt(sqr(p1.x-p2.x)+sqr(p1.y-p2.y));
}
struct line
{
point ps;
real x,y;
line(){}
line(point p1,point p2)
{
ps=p1;
x=p2.x-p1.x;
y=p2.y-p1.y;
}
point spos()
{
return ps;
}
point tpos()
{
return point(ps.x+x,ps.y+y);
}
bool inside(point pt)
{
return sgn(sqrt(x*x+y*y)-dis(ps,pt)-dis(tpos(),pt))==;
}
point get_point(real xx)
{
return point(xx,ps.y+y/x*(xx-ps.x));
}
void operator *=(real k)
{
x*=k;y*=k;
}
void print()
{
printf("Line:[%.2lf,%.2lf]->[%.2lf,%.2lf]\n",ps.x,ps.y,ps.x+x,ps.y+y);
}
}lst[MAXN];
int topl=-;
real xmul(line l1,line l2)
{
return l1.x*l2.y-l1.y*l2.x;
}
line operator -(line l1)
{
l1.ps=l1.tpos();
l1.x=-l1.x;
l1.y=-l1.y;
return l1;
}
bool parallel(line l1,line l2)
{
return !sgn(xmul(l1,l2));
}
point crossover(line l1,line l2)
{
real s1=-xmul(line(l2.spos(),l1.spos()),l1);
real s2=xmul(line(l2.tpos(),l1.spos()),l1);
return point(l2.ps.x+l2.x*s1/(s1+s2), l2.ps.y+l2.y*s1/(s1+s2));
}
point pl[MAXN*MAXN];
int topp=-;
bool cmp_x(point p1,point p2)
{
return sgn(p1.x-p2.x)<;
}
bool equal_x(point p1,point p2)
{
return sgn(p1.x-p2.x)==;
}
line seq[MAXN];
bool cmp_line(line l1,line l2)
{
point p1,p2;
if (l1.x>=)
p1=l1.spos();
else
p1=l1.tpos();
if (l2.x>=)
p2=l2.spos();
else
p2=l2.tpos();
if (sgn(p1.y-p2.y)==)
{
if (l1.x>=)
p1=l1.tpos();
else
p1=l1.spos();
if (l2.x>=)
p2=l2.tpos();
else
p2=l2.spos();
return p1.y>p2.y;
}else
{
return p1.y>p2.y;
}
} int main()
{
freopen("input.txt","r",stdin);
int n;
point p1,p2,p3;
scanf("%d",&n);
for (int i=;i<n;i++)
{
p1.read();
p2.read();
p3.read();
lst[++topl]=line(p1,p2);
lst[++topl]=line(p2,p3);
lst[++topl]=line(p3,p1);
if (xmul(-lst[topl-],lst[topl])<)
{
lst[topl]=-lst[topl];
lst[topl-]=-lst[topl-];
lst[topl-]=-lst[topl-];
}
}
point pt;
for (int i=;i<=topl;i++)
{
for (int j=i+;j<=topl;j++)
{
pt=crossover(lst[i],lst[j]);
if (lst[i].inside(pt) && lst[j].inside(pt))
pl[++topp]=pt;
}
}
sort(pl,pl+topp+,cmp_x);
topp=unique(pl,pl+topp+,equal_x)-pl-;//***
real a,b;
line lt;
real ans=;
for (int i=;i<=topp;i++)
{
a=pl[i-].x;
b=pl[i].x;
int tops=-;
for (int j=;j<=topl;j++)
{
lt=lst[j];
if ((lt.spos().x<lt.tpos().x && sgn(lt.spos().x-a)<= && sgn(b-lt.tpos().x)<=)
|| (lt.spos().x>lt.tpos().x && sgn(lt.tpos().x-a)<= && sgn(b-lt.spos().x)<=))
{
if (lt.spos().x<lt.tpos().x)
{
lt.ps=lt.get_point(a);
lt*=(b-a)/lt.x;
seq[++tops]=lt;
}else
{
lt.ps=lt.get_point(b);
lt*=(a-b)/lt.x;
seq[++tops]=lt;
}
}
}
sort(seq,seq+tops+,cmp_line);
/* printf("Segment:%.2lf %.2lf\n",a,b);
for (int j=0;j<=tops;j++)
seq[j].print();*/
int cnt=;
for (int j=;j<=tops;j++)
{
if (seq[j].x>=)
{
cnt++;
if (cnt==)
ans+=(seq[j].spos().y+seq[j].tpos().y)*seq[j].x/;
}
else
{
cnt--;
if (cnt==)
ans+=(seq[j].spos().y+seq[j].tpos().y)*seq[j].x/;
}
}
}
printf("%.2lf\n",ans);
return ;
}

bzoj 1845: [Cqoi2005] 三角形面积并 扫描线的更多相关文章

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

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

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

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

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

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

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

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

  5. 【BZOJ1845】[Cqoi2005] 三角形面积并 几何+扫描线

    [BZOJ1845][Cqoi2005] 三角形面积并 Description 给出n个三角形,求它们并的面积. Input 第一行为n(N < = 100), 即三角形的个数 以下n行,每行6 ...

  6. [CQOI2005]三角形面积并

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

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

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

  8. BZOJ 1845三角形面积并

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1845 给定100个三角形,求三角形面积并. 戴神模板太可怕.直接调用函数秒掉.思路 ...

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

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

随机推荐

  1. 打造强大的BaseModel(2):让Model实现自动映射,将字典转化成Model

    打造强大的BaseModel(1):让Model自我描述 这篇文章将讲述Model一项更高级也最常用的功能,让Model实现自动映射–将字典转化成Model(所有代码全由Swift实现) 将JSON转 ...

  2. 如何使用axis2 构建 Android 服务器后端--- 工具准备与环境配置

    最近一个项目要做个android端的实验室器材管理系统.小伙伴英勇地接下android端的锅,我就 负责给他写后端,最近看到axis2 这个webservice挺好用的,折腾了几天给大家分享下: 1. ...

  3. DataContext 数据在F5刷新频繁,会出现数据读取错误

    DataContext 数据在F5刷新频繁,会出现数据读取错误 DataContext是 Linq to sql数据模型的底层数据库对象所有LInq数据表对象都是由它派生的, 只要建立一个数据库操作, ...

  4. windows8 8.1 安装完 ubuntu无法挂载 ntfs分区 解决方法

    windows8 8.1 安装完 ubuntu无法挂载 ntfs分区 解决方法: 最近安装完发现8.1系统后,ubuntu无法加载以前的ntfs分区了,特别是我添加到了/etc/fstab里面了 导致 ...

  5. HTML_常见命令学习笔记

    1. java类中的这段代码 out.println(" <div class='line'>"); out.println(" <div align= ...

  6. C++ socket开发1

    服务端 setlocale(LC_ALL,"Chinese-simplified"); WORD wVersionRequested; WSADATA wsaData; int e ...

  7. Fxcop 初体验

    代码质量对于软件项目的成败很重要,这点我想大家都明白.那么在一个软件团队中如何保证代码质量呢?对于这个问题不同的人可能会有不同的答案,对于我而言我觉得做好两点代码质量基本就可以保证了: 1.代码规范( ...

  8. 10.26_地图应用, OSC_doc文档集合,node-webkit

    (1)地图:关于电子地图的加载.展示方式,知乎上有篇文章写的很好:http://www.zhihu.com/question/21530085对于地图的导航距离计算呢?原理是什么? (2)node-w ...

  9. 00_ForTest

    -----该页是爬虫的测试页请忽略------- 1234545@qq.comadasdsdasdsad阿打算多少其热情为 asdasdasdasd4w5wsdvv啊实打实大 啊实打实大asdasda ...

  10. STL之优先队列

    STL 中优先队列的使用方法(priority_queu) 基本操作: empty() 如果队列为空返回真 pop() 删除对顶元素 push() 加入一个元素 size() 返回优先队列中拥有的元素 ...