ZOJ 3993 - Safest Buildings - [數學題]
阿新 • • 發佈:2017-11-05
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 - [數學題]