zoukankan      html  css  js  c++  java
  • Shadow of Survival

    Shadow of Survival

    题目链接:http://dutacm.club:7217/codesheaven/problem.php?id=1083

    题目大意:给出一个由圆台构成的塔和一个点光源,问塔的阴影面积.

    Simpson积分

    注意到圆台底面由点光源投影后仍为圆(对应弦成正比),于是就与这道题类似http://www.cnblogs.com/barrier/p/6512826.html.不再赘述,经测试eps取1e-5时最优.

    /*需要注意的是,#define Abs(x) (x>0?x:-x) 这种写法可能会因为x为复合表达式而导致运算错误*/

    代码如下:

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <iostream>
     4 #define N 1005
     5 using namespace std;
     6 const double eps=1e-5;
     7 const double inf=1e12;
     8 double d,z;
     9 int n,k;
    10 int dcmp(double x){
    11     if(fabs(x)<eps)return 0;
    12     else return x<0?-1:1;
    13 };
    14 struct point{
    15     double x,y;
    16     point(double X=0,double Y=0){x=X;y=Y;}
    17 };
    18 struct circle{
    19     point o;
    20     double r;
    21     circle(point O=point(0,0),double R=0){o=O;r=R;}
    22     bool within(circle tmp){
    23         return fabs(o.x-tmp.o.x)-fabs(r-tmp.r)<=0;
    24     }
    25     bool xin(double x){
    26         return o.x-r<=x&&x<=o.x+r;
    27     }
    28 }c[N];
    29 struct line{
    30     point s,t;
    31     double k,b;
    32     line(point S=point(-1,0),point T=point(1,0)){
    33         s=S;t=T;
    34         if(s.x>t.x)swap(s,t);
    35         k=(s.y-t.y)/(s.x-t.x);
    36         b=s.y-k*s.x;
    37     }
    38     bool xin(double x){
    39         return s.x<=x&&x<=t.x;
    40     }
    41     double f(double x){
    42         return k*x+b;
    43     }
    44 }l[N];
    45 void init(){
    46     scanf("%lf",&c[0].r);
    47     c[0].o=point(0,0);
    48     k=0;
    49     for(int i=1;i<n;++i){
    50         double h,r;
    51         scanf("%lf%lf",&h,&r);
    52         c[i]=circle(point(h*d/(z-h),0),z*r/(z-h));
    53     }
    54     for(int i=1;i<n;++i){
    55         if(c[i].within(c[i-1]))continue;
    56         double sin_theta=(c[i].r-c[i-1].r)/(c[i].o.x-c[i-1].o.x);
    57         double cos_theta=sqrt(1-sin_theta*sin_theta);
    58         l[k++]=line(point(c[i-1].o.x-c[i-1].r*sin_theta,c[i-1].r*cos_theta),
    59                     point(c[i].o.x-c[i].r*sin_theta,c[i].r*cos_theta));
    60     }
    61 }
    62 double F(double x){
    63     double len=0;
    64     for(int i=0;i<n;++i){
    65         if(c[i].xin(x)){
    66             double d=c[i].o.x-x;
    67             len=max(len,2*sqrt(c[i].r*c[i].r-d*d));
    68         }
    69     }
    70     for(int i=0;i<k;++i)
    71         if(l[i].xin(x))
    72             len=max(len,2*l[i].f(x));
    73     return len;
    74 }
    75 double cal(double l,double r){
    76     return (F(l)+4*F((l+r)/2)+F(r))/6*(r-l);
    77 }
    78 double simpson(double l,double r,double s){
    79     double mid=(l+r)/2;
    80     double x=cal(l,mid),y=cal(mid,r);
    81     if(!dcmp(x+y-s))return s;
    82     else return simpson(l,mid,x)+simpson(mid,r,y);
    83 }
    84 void solve(){
    85     double L=inf,R=-inf;
    86     for(int i=0;i<n;++i){
    87         L=min(L,c[i].o.x-c[i].r);
    88         R=max(R,c[i].o.x+c[i].r);
    89     }
    90     printf("%.2lf
    ",simpson(L,R,cal(L,R)));
    91 }
    92 int main(void){
    93     while(~scanf("%lf%lf%d",&d,&z,&n)){
    94         init();
    95         solve();
    96     }
    97 }
  • 相关阅读:
    docker-dockerfile构建与部署nginx
    淘宝镜像安装
    css3 中的变量 var 的使用
    CSS样式清除
    css 样式初始化(rem兼容)
    canvas截屏网页为图片下载到本地-html2canvas.js
    移除JSON对象中的某个属性
    js 常用方法集合(持续更新)
    小程序获取上个页面vm对象 解决百度小程序返回上一页不更新onShow更新(适用于uni-app)
    小程序 请求Promise简单封装
  • 原文地址:https://www.cnblogs.com/barrier/p/6523759.html
Copyright © 2011-2022 走看看