题意:
在一个平面坐标系中,有一个半径为R的圆(R=10101010)(R=10101010),其圆心在原点处。给出平面上N个点(N≤100),现在随机得到一个圆内的点,它会选择与它距离最近的一个点,(如果同时有多个,选择编号最小的一个),现在求给出的N个点中,每个点被选中的概率。
给出的点的坐标(x,y)满足|x|,|y|≤106|x|,|y|≤106
分析:
如果对极限的思想有一定的理解,那么这道题就变得非常非常水了,考虑到R极大,与给出点的坐标范围相比,就可以近似地看作是无限大。
这样一来,我们考虑求出给出点的凸包,凸包内部的面积相对于外部的无限大来说,可以忽略不计,所以我们可以忽略随机到凸包内部某点的情况。
我们发现,白色区域的面积相对于其他的面积来说,在极限的思想下,是可以忽略不计的,而当点位于同一种颜色时,总会选择同一个点(即区域前的字母)。这个区域的两条边分别于其相邻的,凸包上的边垂直。
在极限的思想下,要比较这几个区域的面积,我们只需要比较,凸包上某点与其对应区域所形成的角的大小。所以求出凸包后,在凸包上遍历一遍:
对凸包上的每个点,求出其相邻的两边的点积(A? ?B? =|A|?|B|?cos<A? ,B? >)(A→?B→=|A|?|B|?cos<A→,B→>)
将这个值除以两边长,再取其相反数,即为我们要求的角的cos值,再用系统函数中的acos,就可以求出比例了。
(注意,这道题有点卡精度)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 110
#define EPS 1e-7
using namespace std;
const double Pi=acos(-1);
struct node{double x,y;int id;node(){}node(double xx,double yy):x(xx),y(yy) {}node operator + (const node &a) const {return node(x+a.x,y+a.y);}node operator - (const node &a) const {return node(x-a.x,y-a.y);}node operator * (const double &t) const {return node(x*t,y*t);}double operator *(const node &a) const{return x*a.x+y*a.y;}double operator ^(const node &a) const{return x*a.y-y*a.x;}bool operator <(const node &a) const {return fabs(y-a.y)<EPS?x<a.x:y<a.y;}
}p[MAXN],l1[MAXN];
stack<node> s1,s;
double ans[MAXN];
int n,cnt1;
void solve(node a1[],int &cnt){s.push(p[1]);s1.push(p[1]);s1.push(p[2]);for(int i=3;i<=n;i++){while(!s.empty()&&((p[i]-s.top())^(s1.top()-s.top()))<-EPS){s.pop();s1.pop();}s.push(s1.top());s1.push(p[i]);}while(!s1.empty()){a1[++cnt]=s1.top();s1.pop();}while(!s.empty())s.pop();
}
bool cmp(node a,node b){return b<a;
}
double len(node a){return sqrt(a.x*a.x+a.y*a.y);
}
pair<long long,long long> b[MAXN];
bool check(){for(int i=1;i<=n;i++){b[i].first=(long long)(p[i].x);b[i].second=(long long)(p[i].y);}for(int i=2;i<n;i++){long long xx1=b[i].first-b[i-1].first;long long xx2=b[i+1].first-b[i].first;long long yy1=b[i].second-b[i-1].second;long long yy2=b[i+1].second-b[i].second;if(yy1*xx2!=yy2*xx1)return 0;}return 1;
}
int main(){//freopen("data.in","r",stdin);//freopen("data.out","w",stdout);SF("%d",&n);for(int i=1;i<=n;i++){SF("%lf%lf",&p[i].x,&p[i].y);p[i].id=i;}sort(p+1,p+1+n);if(n==2){PF("0.50000\n");for(int i=2;i<n;i++)PF("0.00000\n");PF("0.50000\n");return 0;}solve(l1,cnt1);sort(p+1,p+1+n,cmp);cnt1--;solve(l1,cnt1);cnt1--;for(int i=1;i<=cnt1;i++){int las,nxt;if(i==1)las=cnt1;elselas=i-1;if(i==cnt1)nxt=1;elsenxt=i+1;double d=((l1[nxt]-l1[i])*(l1[las]-l1[i]))/(len(l1[nxt]-l1[i])*len(l1[las]-l1[i]));//PF("[%lf]",fabs((l1[nxt]-l1[i])*(l1[i]-l1[las])));d=acos(-d);ans[l1[i].id]=d/(2.0*Pi);}for(int i=1;i<=n;i++)PF("%.20lf\n",ans[i]);
}