题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2178

先看到这篇博客:https://www.cnblogs.com/heisenberg-/p/6740654.html

好像本应算弓形面积、三角形面积之类的,但不会...于是用辛普森积分硬做...

参考了这篇博客:https://blog.csdn.net/orpinex/article/details/7311363

然而如果写成精度友好型的 asr ( *15, /15, eps/2 ),或T或RE的,不精度友好反而好了...

为什么一开始传的范围是所有圆边界的 min, max 就会WA,传 -inf, inf 就A了...

总之写的时候还是尽量稳妥一点吧...

代码如下:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. using namespace std;
  6. typedef double db;
  7. int const xn=,inf=;
  8. db const eps=1e-;
  9. int n;
  10. bool tmp[xn];
  11. struct N{int x,y,r;}c[xn];
  12. struct S{db l,r;}seg[xn];
  13. int rd()
  14. {
  15. int ret=,f=; char ch=getchar();
  16. while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
  17. while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
  18. return f?ret:-ret;
  19. }
  20. int dmp(db x)
  21. {
  22. if(fabs(x)<eps)return ;
  23. else if(x>eps)return ;
  24. else return -;
  25. }
  26. db sqr(db x){return x*x;}
  27. bool cmp(S a,S b){return dmp(a.l-b.l)<||(dmp(a.l-b.l)==&&dmp(a.r-b.r)<);}
  28. bool cmp2(N a,N b){return a.r<b.r;}
  29. db maxx(db x,db y){if(dmp(x-y)<)return y; return x;}
  30. bool in(int a,int b){return sqr(c[a].x-c[b].x)+sqr(c[a].y-c[b].y)<=sqr(c[a].r-c[b].r);}
  31. void init()
  32. {
  33. sort(c+,c+n+,cmp2);
  34. for(int i=;i<=n;i++)
  35. {
  36. for(int j=i+;j<=n;j++)
  37. if(in(i,j)){tmp[i]=; break;}
  38. }
  39. int tot=;
  40. for(int i=;i<=n;i++)if(!tmp[i])c[++tot]=c[i];
  41. n=tot;
  42. }
  43. db f(db x)
  44. {
  45. int cnt=;
  46. for(int i=;i<=n;i++)
  47. {
  48. if(dmp(fabs(c[i].x-x)-c[i].r)>)continue;
  49. db dis=sqrt(sqr(c[i].r)-sqr(x-c[i].x));
  50. seg[++cnt].l=c[i].y-dis; seg[cnt].r=c[i].y+dis;
  51. }
  52. sort(seg+,seg+cnt+,cmp);
  53. db ret=,r=-inf;
  54. for(int i=;i<=cnt;i++)
  55. {
  56. if(dmp(seg[i].l-r)>)ret+=seg[i].r-seg[i].l,r=seg[i].r;
  57. else if(dmp(seg[i].r-r)>)ret+=seg[i].r-r,r=seg[i].r;
  58. }
  59. return ret;
  60. }
  61. db simp(db l,db r){return (r-l)/*(f(l)+*f((l+r)/)+f(r));}
  62. db asr(db l,db r,db eps,db lst)
  63. {
  64. db mid=(l+r)/;
  65. db ls=simp(l,mid),rs=simp(mid,r);
  66. if(fabs(ls+rs-lst)<=*eps)return ls+rs+(ls+rs-lst)/;
  67. return asr(l,mid,eps/,ls)+asr(mid,r,eps/,rs);
  68. }
  69. db asr(db l,db r,db lst)
  70. {
  71. db mid=(l+r)/;
  72. db ls=simp(l,mid),rs=simp(mid,r);
  73. if(fabs(ls+rs-lst)<=eps)return ls+rs;
  74. return asr(l,mid,ls)+asr(mid,r,rs);
  75. }
  76. int main()
  77. {
  78. n=rd(); int L=inf,R=-inf;
  79. for(int i=;i<=n;i++)
  80. c[i].x=rd(),c[i].y=rd(),c[i].r=rd(),
  81. L=min(L,c[i].x-c[i].r),R=max(R,c[i].x+c[i].r);
  82. init();
  83. //printf("%.3f\n",asr(L,R,eps,simp(L,R)));
  84. //printf("%.3f\n",asr(L,R,simp(L,R)));
  85. printf("%.3f\n",asr(-inf,inf,simp(-inf,inf)));
  86. //printf("%.3f\n",asr(-inf,inf,eps,simp(-inf,inf)));
  87. return ;
  88. }

然而这样其实会错HAHA,随便来个数据竟然就错了:

3
0 0 1
0 0 1
100 100 1

应该输出 6.283,但上面的代码以及许多题解输出都是 3.142 ...

于是换了一种写法,对每个连续段做积分,这样避免了空白区域对积分结果的影响;

而且发现求一次 f(x) 很慢,所以之前求过的尽量重复利用;

然后就T了,调了两小时...

TLE 的原因竟然是 sort 里面传了 cmp() 函数??!!!如果改成重载结构体小于号,就不T了呵呵-_-

所以还是要注意代码习惯阿。

代码如下:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. using namespace std;
  6. typedef double db;
  7. int const xn=,inf=;
  8. db const eps=1e-;
  9. int n,st,ed,xl[xn],xr[xn];
  10. bool tmp[xn];
  11. struct N{
  12. int x,y,r;
  13. bool operator < (const N &b) const
  14. {return r<b.r;}
  15. }c[xn];
  16. struct S{
  17. db l,r;
  18. bool operator < (const S &b) const
  19. {return l<b.l;}
  20. }seg[xn];
  21. int rd()
  22. {
  23. int ret=,f=; char ch=getchar();
  24. while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
  25. while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
  26. return f?ret:-ret;
  27. }
  28. db sqr(db x){return x*x;}
  29. //bool cmp(S a,S b){return a.l<b.l;}
  30. //bool cmp2(N a,N b){return a.r<b.r;}
  31. bool cmp3(N a,N b){return a.x-a.r<b.x-b.r;}
  32. bool in(int a,int b){return sqr(c[a].x-c[b].x)+sqr(c[a].y-c[b].y)<=sqr(c[a].r-c[b].r);}
  33. void init()
  34. {
  35. sort(c+,c+n+);//cmp2
  36. for(int i=;i<=n;i++)
  37. {
  38. for(int j=i+;j<=n;j++)
  39. if(in(i,j)){tmp[i]=; break;}
  40. }
  41. int tot=;
  42. for(int i=;i<=n;i++)if(!tmp[i])c[++tot]=c[i];
  43. n=tot;
  44. sort(c+,c+n+,cmp3);//
  45. }
  46. db f(db x)
  47. {
  48. int cnt=;
  49. for(int i=st;i<=ed;i++)
  50. {
  51. if(xl[i]>=x||xr[i]<=x)continue;
  52. db dis=sqrt(c[i].r-sqr(x-c[i].x));//(sqr)
  53. seg[++cnt].l=c[i].y-dis; seg[cnt].r=c[i].y+dis;
  54. }
  55. sort(seg+,seg+cnt+);//cmp
  56. db ret=,r=-inf;
  57. for(int i=,j;i<=cnt;i=j)
  58. {
  59. r=seg[i].r;
  60. for(j=i+;j<=cnt&&seg[j].l<=r;j++)
  61. if(r<seg[j].r)r=seg[j].r;
  62. ret+=r-seg[i].l;
  63. }
  64. return ret;
  65. }
  66. db simp(db len,db fl,db fr,db fm){return len/*(fl+*fm+fr);}
  67. db asr(db l,db r,db mid,db fl,db fr,db fm,db lst)
  68. {
  69. db lmid=(l+mid)/,flm=f(lmid),rmid=(mid+r)/,frm=f(rmid);
  70. db ls=simp(mid-l,fl,fm,flm),rs=simp(r-mid,fm,fr,frm);
  71. if(fabs(ls+rs-lst)<=eps)return ls+rs;
  72. return asr(l,mid,lmid,fl,fm,flm,ls)+asr(mid,r,rmid,fm,fr,frm,rs);
  73. }
  74. int main()
  75. {
  76. n=rd();
  77. for(int i=;i<=n;i++)
  78. c[i].x=rd(),c[i].y=rd(),c[i].r=rd();
  79. init(); db ans=;
  80. for(int i=;i<=n;i++)
  81. xl[i]=c[i].x-c[i].r,xr[i]=c[i].x+c[i].r,c[i].r=c[i].r*c[i].r;
  82. for(int i=,j;i<=n;i=j)
  83. {
  84. int l=xl[i],r=xr[i];
  85. for(j=i+;xl[j]<=r&&j<=n;j++)if(xr[j]>r)r=xr[j];
  86. st=i; ed=j-; db mid=(l+r)/;
  87. db fl=f(l),fm=f(mid),fr=f(r);
  88. ans+=asr(l,r,mid,fl,fr,fm,simp(r-l,fl,fr,fm));
  89. }
  90. printf("%.3f\n",ans);
  91. return ;
  92. }

bzoj 2178 圆的面积并 —— 辛普森积分的更多相关文章

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

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

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

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

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

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

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

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

  5. [BZOJ 2178] 圆的面积并 【Simpson积分】

    题目链接:BZOJ - 2178 题目分析 用Simpson积分,将圆按照 x 坐标分成连续的一些段,分别用 Simpson 求. 注意:1)Eps要设成 1e-13  2)要去掉被其他圆包含的圆. ...

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

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

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

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

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

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

  9. BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]

    1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1070  Solved: 596[Submit][Status] ...

随机推荐

  1. shell 字符串处理汇总(查找,替换等等)

    字符串: 简称“串”.有限字符的序列.数据元素为字符的线性表,是一种数据的逻辑结构.在计算机中可有不同的存储结构.在串上可进行求子串.插入字符.删除字符.置换字符等运算. 字符: 计算机程序设计及操作 ...

  2. 九度OJ 1261:寻找峰值点 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:500 解决:37 题目描述: 给定一个整数序列,该整数序列存在着这几种可能:先递增后递减.先递减后递增.全递减.全递增. 请找出那个最大值的 ...

  3. nginx学习之简化安装篇(一)

    环境:CentOS 6.5 1. 安装依赖环境 [root@localhost ~]# yum install pcre-devel zlib-devel openssl-devel -y 2. 安装 ...

  4. c++操作flash

    c++操作falsh,忘了原文在哪了,自己尝试了,直接贴代码 // SDK版本 //////////////////////////////////////////////////////////// ...

  5. persisted? vs new_record?

    https://joe11051105.gitbooks.io/you-need-to-know-about-ruby-on-rails/content/activerecord/persisted_ ...

  6. Kattis - fairdivision 【贪心】

    题意 有一堆人 要给他们的朋友 买一个生日礼物,然后 每个人 给出自己的最大负担额度 并且给出礼物总价 然后要给出一种解决方案 尽量让 所有人的支出都接近平均,如果实在无法平均,那就让 先来的人 多处 ...

  7. 【leetcode刷题笔记】Spiral Matrix II

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  8. P4240 毒瘤之神的考验

    题目 P4240 毒瘤之神的考验 神仙题\(emmm\) 前置 首先有一个很神奇的性质: \(\varphi(ij)=\dfrac{\varphi(i)\varphi(j)gcd(i,j)}{\var ...

  9. POJ 之 1002 :487-3279

    487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 242418   Accepted: 42978 Descr ...

  10. 算法(Algorithms)第4版 练习 1.5.12

    package com.qiusongde; import edu.princeton.cs.algs4.StdIn; import edu.princeton.cs.algs4.StdOut; pu ...