1. 程式人生 > >ZOJ 3993 - Safest Buildings - [數學題]

ZOJ 3993 - Safest Buildings - [數學題]

str 一個點 min poi 原來 -- ans () its

題目鏈接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3993

題意:

給出n幢建築,每個都以一個點表示,給出點坐標。

有一個以原點為圓心,以R為半徑的圓,記為圓O,是原始安全範圍;

then,安全範圍變為在原來那個圓內任意位置的以r為半徑的圓(不會超出原來的圓),記為圓P;

求縮圈後,仍在安全範圍內的概率最大的,所有的點。

題解:

怎麽求概率?

對於一幢建築(或者說一個點),以其為圓心,做一個以半徑為2r的圓Q;

圓Q在圓O內的面積,除以圓O的面積,得到的商即為這個點對應的概率。

顯然這個概率,有關於:“點和原點的距離”;

當R>2*r 時,

在以原點為圓心,以R-2*r為半徑的圓的範圍內的點,安全概率最高且全部相同;

如果不存在這樣的點,則越靠近原點越安全;

當R<=2*r時,

在以原點為圓心,以2*r-R為半徑的圓的範圍內的點,安全概率最高且全部相同;

如果不存在這樣的點,則越靠近原點越安全;

AC代碼:

#include<bits/stdc++.h>
struct Point{
    int id;
    double d;
}p[105];
int n;
double R,r;
int ans[105],ans_cnt;
int main()
{
    int t;
    scanf(
"%d",&t); while(t--) { scanf("%d%lf%lf",&n,&R,&r); double SameSafe_R = fabs(R-2*r); double mini_d = 0x3f3f3f3f; ans_cnt=0; for(int i=1,x,y;i<=n;i++) { scanf("%d%d",&x,&y); p[i].id=i; p[i].d
=sqrt(x*x+y*y); if(p[i].d<=SameSafe_R) ans[ans_cnt++]=p[i].id; if(p[i].d<mini_d) mini_d=p[i].d; } if(ans_cnt>0) { printf("%d\n",ans_cnt); for(int i=0;i<ans_cnt;i++) { if(i!=0) printf(" "); printf("%d",ans[i]); } printf("\n"); } else { for(int i=1;i<=n;i++) if(p[i].d<=mini_d) ans[ans_cnt++]=p[i].id; printf("%d\n",ans_cnt); for(int i=0;i<ans_cnt;i++) { if(i!=0) printf(" "); printf("%d",ans[i]); } printf("\n"); } } }

PS.比較奇怪的一點是,用vector會WA,用數組就不會。

ZOJ 3993 - Safest Buildings - [數學題]