[CQOI2005]三角形面积并
[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]三角形面积并的更多相关文章
- bzoj 1845: [Cqoi2005] 三角形面积并 扫描线
1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 848 Solved: 206[Submit][Statu ...
- BZOJ 1845: [Cqoi2005] 三角形面积并 [计算几何 扫描线]
1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1151 Solved: 313[Submit][Stat ...
- 【BZOJ1845】[Cqoi2005] 三角形面积并 几何+扫描线
[BZOJ1845][Cqoi2005] 三角形面积并 Description 给出n个三角形,求它们并的面积. Input 第一行为n(N < = 100), 即三角形的个数 以下n行,每行6 ...
- CQOI2005 三角形面积并 和 POJ1177 Picture
1845: [Cqoi2005] 三角形面积并 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1664 Solved: 443[Submit][Stat ...
- BZOJ1845 [Cqoi2005] 三角形面积并 扫描线 计算几何
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1845 题意概括 给出n个三角形,求其面积并. 题解 有一个很经典的扫描线题目:矩形面积并.那个比较 ...
- BZOJ1845 : [Cqoi2005] 三角形面积并
求出所有交点后从左往右扫描线,用每段的中位线去截所有三角形,算出长度并后乘以该段长度即可,时间复杂度$O(n^3\log n)$. #include<cstdio> #include< ...
- BZOJ 1845: [Cqoi2005] 三角形面积并 (辛普森积分)
大力辛普森积分 精度什么的搞了我好久- 学到了Simpson的一个trick 深度开11,eps开1e-4.跑的比有些扫描线还快- CODE #include <bits/stdc++.h> ...
- ytu 1058: 三角形面积(带参的宏 练习)
1058: 三角形面积 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 190 Solved: 128[Submit][Status][Web Boar ...
- UVa 11437:Triangle Fun(计算几何综合应用,求直线交点,向量运算,求三角形面积)
Problem ATriangle Fun Input: Standard Input Output: Standard Output In the picture below you can see ...
随机推荐
- linux下的抓包
1. 查看网卡名字 cat /proc/net/dev 2.抓取外网进来的包 tcpdump -i eth0 port -s -w .pcap 3.抓取自己服务器上的两个程序之间访问的数据 换成 lo ...
- jenkins权限管理,实现不同用户组显示对应视图views中不同的jobs
如何分组管理权限,如何实现不同用户组显示对应视图views中不同的jobs,建议使用Role Strategy Plugin插件. 1.安装Role Strategy Plugin插件. 2.“系统管 ...
- 论文阅读笔记十:DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs (DeepLabv2)(CVPR2016)
论文链接:https://arxiv.org/pdf/1606.00915.pdf 摘要 该文主要对基于深度学习的分割任务做了三个贡献,(1)使用空洞卷积来进行上采样来进行密集的预测任务.空洞卷积可以 ...
- Ubuntu 进入、退出命令行的快捷键
进入: Ctrl+Alt+F1 退出: Ctrl+Alt+F7(或者 Alt+F7) 进入命令行窗口:Ctrl+Alt+T
- 插件使用一顶部消息提示---overhang
overhang 是一个非常好的消息提示插件,它是在顶部提示. 官方网站:https://github.com/paulkr/overhang.js 使用方法 1.引入jquery库和jqeury u ...
- 三 os模块
os模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相 ...
- Ubuntu下Gradle环境配置
sudo gedit ~/.profile sudo source ~/.profile env # for java export JAVA_HOME=/home/cmm/jdk export CL ...
- 用jQuery实现Ajax
前置知识:ajax原理,json字符串进行信息传递. Ajax主要的功能是实现了浏览器端 异步 访问服务器:通过浏览器的XMLHttpRequest对象发出小部分数据,与服务端进行交互, 服务端返回小 ...
- 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 ...
- python安装plinter
我下的python2.7是有pip的,但是直接在cmd中输入pip是无响应的.要去环境变量中配置D:/python/Script 这样就可以了. pip install splinter就能下载了