[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自定义TabWidget
在做项目的时候,需要用到这个选项卡,刚开始看了系统的tabwidget,囧了,底边有黑线不说,还不美观,扒了好多的网页发现前辈做的能够满足自己的需求,将代码修改了下,就能用喽,伟人说过,站在前辈的肩膀 ...
- android音乐播放器开发 SweetMusicPlayer 播放本地音乐
上一篇写了载入歌曲列表,http://blog.csdn.net/huweigoodboy/article/details/39856411,如今来总结下播放本地音乐. 一,MediaPlayer 首 ...
- Windows 下多线程编程技术
(1) 线程的创建:(主要以下2种) CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID lParam, int nPrio ...
- Android(java)学习笔记181:利用Service在后台播放背景音乐
1.在android应用程序里,有一种没有UI的类(android.app.Service)——Service.简单来说,Service是一个 background process(背景程序),通过背 ...
- .Net程序员学习Linux(三)
基础命令 ll 文件名 命令可以查看文件的大小 file 文件名 可以看到文件后缀,大小 压缩与解压工具 这些压缩工具按照我理解应该是很少单独拿出来用,应该是需要配合其他命令或者工具来使用 gzi ...
- getSharedPreferences()与getSharedPreferences()与getDefaultSharedPreferences()的区别
http://blog.csdn.net/ah200614435/article/details/7869681 一直迷惑于这三个方法的关系,最近忙完项目,好好的分析一下. 如果你熟悉Context那 ...
- google map getLocation参考
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- 详细介绍Linux shell脚本基础学习
Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提.1. Lin ...
- ENC28J60 + M430G2553,用uip搭建http服务器,解决“在XP系统下可以访问,在Win7下不能访问”的问题
近日,用ENC28J60,在M430G2553上搭建一个简单的HTTP服务器,结果发现在XP系统下可以访问,在Win7下不能访问,非常奇葩的问题. 通过抓包,如下图,计算机(IP地址为192.168. ...
- 如何在本地安装测试ECSHOP 转载
如何在本地安装测试ECSHOP 如何在本地(自己的电脑)上先安装ECShop 一.创建PHP环境 1.下载AppServ 因为ECShop在线网上商店系统是用PHP语言开发的,所以,在本地架设网店之前 ...