[BZOJ 2178] 圆的面积并 【Simpson积分】
题目链接:BZOJ - 2178
题目分析
用Simpson积分,将圆按照 x 坐标分成连续的一些段,分别用 Simpson 求。
注意:1)Eps要设成 1e-13 2)要去掉被其他圆包含的圆。
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; typedef double LF; const LF Eps = 1e-13; const int MaxN = 1000 + 5; int n, Lc, Rc, Top, Tot; LF Lx, Rx, Ans; inline LF gmin(LF a, LF b) {return a < b ? a : b;}
inline LF gmax(LF a, LF b) {return a > b ? a : b;}
inline LF Sqr(LF x) {return x * x;} struct Point
{
LF x, y;
Point() {}
Point(LF a, LF b)
{
x = a; y = b;
}
}; inline LF Dis(Point p1, Point p2)
{
return sqrt(Sqr(p1.x - p2.x) + Sqr(p1.y - p2.y));
} struct Circle
{
Point o;
LF r;
} C[MaxN], S[MaxN]; inline bool Cmp1(Circle c1, Circle c2)
{
return c1.r < c2.r;
} inline bool Cmp2(Circle c1, Circle c2)
{
return c1.o.x - c1.r < c2.o.x - c2.r;
} bool Del[MaxN]; struct Segment
{
LF l, r;
} Seg[MaxN]; inline bool Cmp3(Segment s1, Segment s2)
{
return s1.l < s2.l;
} inline LF f(LF x)
{
LF ret = 0.0, p, q, Hi;
Top = 0;
for (int i = Lc; i <= Rc; ++i)
{
if (x <= S[i].o.x - S[i].r || x >= S[i].o.x + S[i].r) continue;
Hi = sqrt(Sqr(S[i].r) - Sqr(S[i].o.x - x));
Seg[++Top].l = S[i].o.y - Hi; Seg[Top].r = S[i].o.y + Hi;
}
sort(Seg + 1, Seg + Top + 1, Cmp3);
for (int i = 1, j; i <= Top; ++i)
{
p = Seg[i].l; q = Seg[i].r;
for (j = i + 1; j <= Top; ++j)
{
if (Seg[j].l > q) break;
if (Seg[j].r > q) q = Seg[j].r;
}
ret += q - p; i = j - 1;
}
return ret;
} inline LF Simpson(LF l, LF r, LF fl, LF fmid, LF fr)
{
return (fl + 4.0 * fmid + fr) * (r - l) / 6.0;
} inline LF RSimpson(LF l, LF r, LF fl, LF fmid, LF fr)
{
LF mid, p, q, x, y, z;
mid = (l + r) / 2.0;
p = f((l + mid) / 2.0); q = f((mid + r) / 2.0);
x = Simpson(l, r, fl, fmid, fr);
y = Simpson(l, mid, fl, p, fmid);
z = Simpson(mid, r, fmid, q, fr);
if (fabs(x - y - z) < Eps) return y + z;
else return RSimpson(l, mid, fl, p, fmid) + RSimpson(mid, r, fmid, q, fr);
} int main()
{
scanf("%d", &n);
int a, b, c;
for (int i = 1; i <= n; ++i)
{
scanf("%d%d%d", &a, &b, &c);
C[i].o = Point((LF)a, (LF)b);
C[i].r = (LF)c;
}
sort(C + 1, C + n + 1, Cmp1);
memset(Del, 0, sizeof(Del));
for (int i = 1; i <= n; ++i)
for (int j = i + 1; j <= n; ++j)
if (Dis(C[i].o, C[j].o) <= C[j].r - C[i].r)
{
Del[i] = true;
break;
}
Tot = 0;
for (int i = 1; i <= n; ++i)
if (!Del[i]) S[++Tot] = C[i];
sort(S + 1, S + Tot + 1, Cmp2);
Ans = 0.0;
for (int i = 1, j; i <= Tot; ++i)
{
Lc = i; Rc = i; Lx = S[i].o.x - S[i].r; Rx = S[i].o.x + S[i].r;
for (j = i + 1; j <= Tot; ++j)
{
if (S[j].o.x - S[j].r > Rx) break;
if (S[j].o.x + S[j].r > Rx) Rx = S[j].o.x + S[j].r;
}
Rc = j - 1; i = j - 1;
Ans += RSimpson(Lx, Rx, f(Lx), f((Lx + Rx) / 2.0), f(Rx));
}
printf("%.3lf\n", Ans);
return 0;
}
[BZOJ 2178] 圆的面积并 【Simpson积分】的更多相关文章
- BZOJ 2178 圆的面积并 ——Simpson积分
[题目分析] 史上最良心样例,史上最难调样例. Simpson积分硬上. 听说用long double 精度1e-10才能过. 但是double+1e-6居然过了. [代码] #include < ...
- BZOJ 2178: 圆的面积并 [辛普森积分 区间并]
2178: 圆的面积并 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1740 Solved: 450[Submit][Status][Discus ...
- bzoj 2178 圆的面积并 —— 辛普森积分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2178 先看到这篇博客:https://www.cnblogs.com/heisenberg- ...
- bzoj 2178 圆的面积并——辛普森积分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2178 把包含的圆去掉.横坐标不相交的一段一段圆分开算.算辛普森的时候预处理 f( ) ,比如 ...
- BZOJ 2178: 圆的面积并 (辛普森积分)
code #include <set> #include <cmath> #include <cstdio> #include <cstring> #i ...
- bzoj 2178 圆的面积并【simpson积分】
直接套simpson,f可以直接把圆排序后扫一遍所有圆,这样维护一个区间就可以避免空段. 然而一定要去掉被其他圆完全覆盖的圆,否则会TLE #include<iostream> #incl ...
- 【BZOJ】2178: 圆的面积并
http://www.lydsy.com/JudgeOnline/problem.php?id=2178 题意:给出n<=1000个圆,求这些圆的面积并 #include <cstdio& ...
- BZOJ 1845: [Cqoi2005] 三角形面积并 (辛普森积分)
大力辛普森积分 精度什么的搞了我好久- 学到了Simpson的一个trick 深度开11,eps开1e-4.跑的比有些扫描线还快- CODE #include <bits/stdc++.h> ...
- BZOJ 1502 月下柠檬树(simpson积分)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1502 题意:给出如下一棵分层的树,给出每层的高度和每个面的半径.光线是平行的,与地面夹角 ...
随机推荐
- android音乐播放器开发 SweetMusicPlayer 播放本地音乐
上一篇写了载入歌曲列表,http://blog.csdn.net/huweigoodboy/article/details/39856411,如今来总结下播放本地音乐. 一,MediaPlayer 首 ...
- JAVA对象之生
https://yq.aliyun.com/users/1556056716932876?spm=5176.100239.blogrightarea55811.3.6cvyJd
- Chapter 4 - How to Fire some Bullets
Now, we want to let the hero fire some bullets to kill the enemies, add the codes below to set the l ...
- request对象多种方法封装表单数据
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, ...
- iOS 9 关键字的简单使用
前言: 在iOS 9 苹果推出了很多关键字, 目的其实很明确, 主要就是提高开发人员的效率, 有益于程序员之间的沟通与交流, 在开发中代码更加规范! 1. nullable 与 nonnull nul ...
- Shell变量之自定义变量、环境变量
1:环境变量 环境变量可以帮我们达到很多功能-包括家目录的变换啊.提示字符的显示啊.运行文件搜寻的路径啊等等的那么,既然环境变量有那么多的功能,问一下,目前我的 shell 环境中, 有 ...
- linux下的openoffice安装和服务自启动
openoffice下载并安装 wget http://sourceforge.net/projects/openofficeorg.mirror/files/4.1.1/binaries/zh-CN ...
- 关于 复制文本 然后Ctrl+V 操作的这个功能 貌似jq也没有封装。。。
/* * copy */ function copy(){ var maintext=$("#myhtml").val(); alert(maintext); copyToClip ...
- [Mime] QuotedPrintableEncoding帮助类 (转载)
点击下载 QuotedPrintableEncoding.rar 这个类是关于QuotedPrintableEncoding的帮助类看下面代码吧 /// <summary> /// 类说明 ...
- javascript类继承系列三(对象伪装)
原理:在子类的构造器上调用超类构造器(父类构造器中的this指向子类实例),js提供了apply()和call()函数,可以实现这种调用 function baseClass() { this.col ...