[CQOI2005]三角形面积并

题目大意:

求\(n(n\le100)\)个三角形的面积并。

思路:

自适应辛普森法,玄学卡精度可过。

源代码:

#include<cmath>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=101;
const double eps=1e-10;
struct Point {
double x,y;
};
struct Triangle {
Point p1,p2,p3;
};
Triangle t[N];
struct Node {
double p;
int v,id;
bool operator < (const Node &rhs) const {
return p<rhs.p;
}
};
std::vector<Node> v;
std::vector<int> c;
inline bool cross(const Point &a,const Point &b,const double &x) {
if(a.x==b.x) return false;
if(a.x<b.x) {
return a.x<=x&&x<b.x;
} else {
return b.x<x&&x<=a.x;
}
}
inline double calc(const Point &a,const Point &b,const double &x) {
return (b.y-a.y)/(b.x-a.x)*(x-a.x)+a.y;
}
inline double F(const double &x) {
std::vector<std::pair<double,int> > v;
for(register unsigned j=0;j<c.size();j++) {
const int &i=c[j];
double q[3];
int h=0;
if(cross(t[i].p1,t[i].p2,x)) {
q[h++]=calc(t[i].p1,t[i].p2,x);
}
if(cross(t[i].p2,t[i].p3,x)) {
q[h++]=calc(t[i].p2,t[i].p3,x);
}
if(cross(t[i].p3,t[i].p1,x)) {
q[h++]=calc(t[i].p3,t[i].p1,x);
}
if(h==2) {
if(q[0]>q[1]) std::swap(q[0],q[1]);
v.push_back(std::make_pair(q[0],1));
v.push_back(std::make_pair(q[1],-1));
}
}
std::sort(v.begin(),v.end());
double st,ans=0;
for(register unsigned i=0,tmp=0;i<v.size();i++) {
if(tmp==0) st=v[i].first;
tmp+=v[i].second;
if(tmp==0) {
ans+=v[i].first-st;
}
}
return ans;
}
inline double simpson(const double &fl,const double &fm,const double &fr,const double &len) {
return (fl+4*fm+fr)*len/6;
}
inline double asr(const double &a,const double &b,const double &fl,const double &fm,const double &fr,const int &d) {
const double c=(a+b)/2;
const double flm=F((a+c)/2),frm=F((c+b)/2);
const double ls=simpson(fl,flm,fm,c-a),rs=simpson(fm,frm,fr,b-c),s=simpson(fl,fm,fr,b-a);
if(fabs(ls+rs-s)<eps&&d>13) return ls+rs;
return asr(a,c,fl,flm,fm,d+1)+asr(c,b,fm,frm,fr,d+1);
}
int main() {
const int n=getint();
for(register int i=1;i<=n;i++) {
scanf("%lf%lf%lf%lf%lf%lf",&t[i].p1.x,&t[i].p1.y,&t[i].p2.x,&t[i].p2.y,&t[i].p3.x,&t[i].p3.y);
v.push_back((Node){std::min(std::min(t[i].p1.x,t[i].p2.x),t[i].p3.x),1,i});
v.push_back((Node){std::max(std::max(t[i].p1.x,t[i].p2.x),t[i].p3.x),-1,i});
}
std::sort(v.begin(),v.end());
int tmp=0,beg;
double ans=0;
for(register unsigned i=0;i<v.size();i++) {
if(tmp==0) beg=i;
tmp+=v[i].v;
if(tmp==0) {
for(register unsigned j=beg;j<=i;j++) {
c.push_back(v[j].id);
}
std::sort(c.begin(),c.end());
c.resize(std::unique(c.begin(),c.end())-c.begin());
const double &st=v[beg].p,&en=v[i].p;
ans+=asr(st,en,F(st),F((st+en)/2),F(en),1);
c.clear();
}
}
printf("%.2f\n",ans);
return 0;
}

[CQOI2005]三角形面积并的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. UVa 11437:Triangle Fun(计算几何综合应用,求直线交点,向量运算,求三角形面积)

    Problem ATriangle Fun Input: Standard Input Output: Standard Output In the picture below you can see ...

随机推荐

  1. linux下的抓包

    1. 查看网卡名字 cat /proc/net/dev 2.抓取外网进来的包 tcpdump -i eth0 port -s -w .pcap 3.抓取自己服务器上的两个程序之间访问的数据 换成 lo ...

  2. jenkins权限管理,实现不同用户组显示对应视图views中不同的jobs

    如何分组管理权限,如何实现不同用户组显示对应视图views中不同的jobs,建议使用Role Strategy Plugin插件. 1.安装Role Strategy Plugin插件. 2.“系统管 ...

  3. 论文阅读笔记十:DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs (DeepLabv2)(CVPR2016)

    论文链接:https://arxiv.org/pdf/1606.00915.pdf 摘要 该文主要对基于深度学习的分割任务做了三个贡献,(1)使用空洞卷积来进行上采样来进行密集的预测任务.空洞卷积可以 ...

  4. Ubuntu 进入、退出命令行的快捷键

    进入: Ctrl+Alt+F1 退出: Ctrl+Alt+F7(或者 Alt+F7) 进入命令行窗口:Ctrl+Alt+T

  5. 插件使用一顶部消息提示---overhang

    overhang 是一个非常好的消息提示插件,它是在顶部提示. 官方网站:https://github.com/paulkr/overhang.js 使用方法 1.引入jquery库和jqeury u ...

  6. 三 os模块

    os模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相 ...

  7. Ubuntu下Gradle环境配置

    sudo gedit ~/.profile sudo source ~/.profile env # for java export JAVA_HOME=/home/cmm/jdk export CL ...

  8. 用jQuery实现Ajax

    前置知识:ajax原理,json字符串进行信息传递. Ajax主要的功能是实现了浏览器端 异步 访问服务器:通过浏览器的XMLHttpRequest对象发出小部分数据,与服务端进行交互, 服务端返回小 ...

  9. POJ 1364 / HDU 3666 【差分约束-SPFA】

    POJ 1364 题解:最短路式子:d[v]<=d[u]+w 式子1:sum[a+b+1]−sum[a]>c      —      sum[a]<=sum[a+b+1]−c−1  ...

  10. python安装plinter

    我下的python2.7是有pip的,但是直接在cmd中输入pip是无响应的.要去环境变量中配置D:/python/Script 这样就可以了. pip install splinter就能下载了