zoukankan      html  css  js  c++  java
  • Bzoj2178 圆的面积并

    Time Limit: 20 Sec  Memory Limit: 259 MB
    Submit: 1720  Solved: 441

    Description

    给出N个圆,求其面积并

    Input

    先给一个数字N ,N< = 1000 接下来是N行是圆的圆心,半径,其绝对值均为小于1000的整数

    Output

    面积并,保留三位小数

    正解是计算几何,也可以用simpson积分强行搞。

    这里解法是simpson积分

    数据炒鸡不友好,精度必须要1e-13才行,于是轻松过SPOJ那道圆面积并的代码被轻松卡掉。

    开始尝试各种细节剪枝,比如说删掉所有被大圆包含的小圆,比如说只算有圆的横坐标而跳过空区域,比如说solve的时候多传一个面积参数……

    然而还是T得飞起,折腾了一下午,突然发现popoQQQ大神在算f(x)的时候加了个记忆化。http://blog.csdn.net/popoqqq/article/details/42292313

    并不会用static,姑且仿照着写了记忆化,成功AC。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<map>
      7 using namespace std;
      8 const double eps=1e-13;
      9 const int INF=1e9;
     10 const int mxn=1010;
     11 int read(){
     12     int x=0,f=1;char ch=getchar();
     13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     14     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
     15     return x*f;
     16 }
     17 //
     18 struct cir{
     19     int x,y,r;
     20     friend bool operator < (const cir a,const cir b){return a.r<b.r;}
     21 }c[mxn];int cnt=0;
     22 inline double dist(cir a,cir b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
     23 //
     24 struct line{
     25     double l,r;
     26     friend bool operator <(const line a,const line b){return a.l<b.l;}
     27 }a[mxn],b[mxn];int lct=0;
     28 
     29 
     30 double f(double x){
     31     static map<double,double>mp;
     32     static map<double,double>::iterator it;
     33     if((it=mp.find(x))!=mp.end())return it->second;
     34     double &re=mp[x];
     35     int i,j;
     36     lct=0;
     37     for(i=1;i<=cnt;i++){//计算直线截得圆弧长度 
     38         double dd=c[i].x-x;
     39         if(fabs(dd)>=c[i].r)continue;
     40         double h= sqrt(c[i].r*c[i].r-dd*dd);
     41         a[++lct].l=c[i].y-h;
     42         a[lct].r=c[i].y+h;
     43     }
     44     if(!lct)return re=0.0;
     45     double last=-INF;
     46     sort(a+1,a+lct+1);
     47     for(i=1;i<=lct;i++){//线段长度并 
     48         if(a[i].l>last){re+=a[i].r-a[i].l;last=a[i].r;}
     49         else if(a[i].r>last){re+=a[i].r-last;last=a[i].r;}
     50     }
     51 //    printf("x:%.3f  len:%.3f
    ",x,len);
     52     return re;
     53 }
     54 inline double sim(double l,double r){
     55     return (f(l)+4*f((l+r)/2)+f(r))*(r-l)/6;
     56 }
     57 double solve(double l,double r,double S){
     58     double mid=(l+r)/2;
     59     double ls=sim(l,mid);
     60     double rs=sim(mid,r);
     61     if(fabs(rs+ls-S)<eps)return ls+rs;
     62     return solve(l,mid,ls)+solve(mid,r,rs);
     63 }
     64 int n;
     65 double ans=0;
     66 bool del[mxn];
     67 int main(){
     68     freopen("cir.in","r",stdin);
     69     n=read();
     70     int i,j;
     71 
     72     for(i=1;i<=n;i++){
     73         c[i].x=read();    c[i].y=read();    c[i].r=read();
     74 //        scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].r);
     75     }
     76     //
     77     sort(c+1,c+n+1);
     78     for(i=1;i<n;i++)
     79         for(j=i+1;j<=n;j++){
     80             if((double)c[j].r-c[i].r>=dist(c[i],c[j]))
     81                 {del[i]=1;break;}
     82         }
     83     for(i=1;i<=n;i++)
     84         if(!del[i])c[++cnt]=c[i];
     85     //删去被包含的圆
     86     double tmp=-INF;int blct=0;
     87     for(i=1;i<=cnt;i++){
     88         b[++blct].l=c[i].x-c[i].r;
     89         b[blct].r=c[i].x+c[i].r;
     90     }
     91     sort(b+1,b+blct+1);
     92     double L=-INF;
     93     for(i=1;i<=blct;i++){
     94         if(b[i].r<=tmp)continue;
     95         L=max(tmp,b[i].l);
     96         ans+=solve(L,b[i].r,sim(L,b[i].r));
     97         tmp=b[i].r;
     98     }
     99     printf("%.3f
    ",ans);
    100     return 0;
    101 }

      

  • 相关阅读:
    VS2012程序打包部署详解
    C# 实现客户端程序自动更新
    C# dev gridcontrol中添加checkbox复选框
    sql server 修改表结构
    sql server 日期转换函数 convert()
    C# devExpress BandedGridView属性 备忘
    sql server 行转列 Pivot UnPivot
    c# 动态产生控件 注册动态控件事件
    阿里云镜像
    git 拉去代码要求密码 解决方法:生成gitLab公钥
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6351792.html
Copyright © 2011-2022 走看看