题目链接: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积分】的更多相关文章

  1. BZOJ 2178 圆的面积并 ——Simpson积分

    [题目分析] 史上最良心样例,史上最难调样例. Simpson积分硬上. 听说用long double 精度1e-10才能过. 但是double+1e-6居然过了. [代码] #include < ...

  2. BZOJ 2178: 圆的面积并 [辛普森积分 区间并]

    2178: 圆的面积并 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1740  Solved: 450[Submit][Status][Discus ...

  3. bzoj 2178 圆的面积并 —— 辛普森积分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2178 先看到这篇博客:https://www.cnblogs.com/heisenberg- ...

  4. bzoj 2178 圆的面积并——辛普森积分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2178 把包含的圆去掉.横坐标不相交的一段一段圆分开算.算辛普森的时候预处理 f( ) ,比如 ...

  5. BZOJ 2178: 圆的面积并 (辛普森积分)

    code #include <set> #include <cmath> #include <cstdio> #include <cstring> #i ...

  6. bzoj 2178 圆的面积并【simpson积分】

    直接套simpson,f可以直接把圆排序后扫一遍所有圆,这样维护一个区间就可以避免空段. 然而一定要去掉被其他圆完全覆盖的圆,否则会TLE #include<iostream> #incl ...

  7. 【BZOJ】2178: 圆的面积并

    http://www.lydsy.com/JudgeOnline/problem.php?id=2178 题意:给出n<=1000个圆,求这些圆的面积并 #include <cstdio& ...

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

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

  9. BZOJ 1502 月下柠檬树(simpson积分)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1502 题意:给出如下一棵分层的树,给出每层的高度和每个面的半径.光线是平行的,与地面夹角 ...

随机推荐

  1. cellspacing cellpadding

    <table border="1" cellspacing="300" cellpadding="100">    <tr ...

  2. iOS内存泄漏自动检测工具PLeakSniffer

    新款objective-C内存泄漏自动检测工具 PLeakSniffer , GitHub地址 (https://github.com/music4kid/PLeakSniffer). 背景 前些天读 ...

  3. 动态jsp页面转PDF输出到页面

    最近工作中遇到不少问题.总结一下.这段代码主要功能是将一个生成JSP页面转发成PDF输出到页面 需要利用ITEXT String html = ServletUtils.forward(request ...

  4. Properties文件,Data,Calendar类的使用

    package cn.hncu.day9; import java.io.FileInputStream;import java.io.FileNotFoundException;import jav ...

  5. Oracle11g新特性导致空表不能导出问题

        ORACLE 11G在用EXP导出时,发现空表(没有数据或者没有用过的表)不能导出了.     查了一下资料,说是Oracle 11G中有个新特性,当表无数据时,不分配segment,以节省空 ...

  6. SQL带参数拼接

    List<SqlParameter> paras = new List<SqlParameter>(); string wherSql = PreWhereSQL + GetQ ...

  7. Django 初探--Django的开发服务器及创建数据库(笔记)

    1.Django的开发服务器 Django框架中包含一些轻量级的web应用服务器,开发web项目时不需再对其配置服务器,Django提供的内置服务器可以在代码修改时自动加载,从而实现网站的迅速开发. ...

  8. PL/SQL Developer 远程连接Oracle数据库

    PL/SQL Developer 远程连接Oracle数据库 网上搜了很多方法,这个可行! 1.    配置服务器tnsnames.ora文件,如果本机上没有安装oracle,可以从安装了oracle ...

  9. php&nbsp;curl_init函数用法

    原文地址:curl_init函数用法">php curl_init函数用法作者:loading 使用PHP的cURL库可以简单和有效地去抓网页.你只需要运行一个脚本,然后分析一下你所抓 ...

  10. order by跟group by 跟having----------------sum() 求和   avg()求平均   count() 求个数--------------like

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoEAAACdCAIAAABEujUmAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWX ...