首页 > 代码库 > [CodeForces - 614C] C - Peter and Snow Blower
[CodeForces - 614C] C - Peter and Snow Blower
C - Peter and Snow Blower
Peter got a new snow blower as a New Year present. Of course, Peter decided to try it immediately. After reading the instructions he realized that it does not work like regular snow blowing machines. In order to make it work, you need to tie it to some point that it does not cover, and then switch it on. As a result it will go along a circle around this point and will remove all the snow from its path.
Formally, we assume that Peter‘s machine is a polygon on a plane. Then, after the machine is switched on, it will make a circle around the point to which Peter tied it (this point lies strictly outside the polygon). That is, each of the points lying within or on the border of the polygon will move along the circular trajectory, with the center of the circle at the point to which Peter tied his machine.
Peter decided to tie his car to point P and now he is wondering what is the area of ??the region that will be cleared from snow. Help him.
Input
The first line of the input contains three integers — the number of vertices of the polygon n (), and coordinates of point P.
Each of the next n lines contains two integers — coordinates of the vertices of the polygon in the clockwise or counterclockwise order. It is guaranteed that no three consecutive vertices lie on a common straight line.
All the numbers in the input are integers that do not exceed 1?000?000 in their absolute value.
Output
Print a single real value number — the area of the region that will be cleared. Your answer will be considered correct if its absolute or relative error does not exceed 10?-?6.
Namely: let‘s assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .
Example
3 0 0
0 1
-1 2
1 2
12.566370614359172464
4 1 -1
0 0
1 2
2 0
1 1
21.991148575128551812
Note
In the first sample snow will be removed from that area:
题目的意思是,给你n+1个点(其中一个是基准点(已知),且两两相异,且是按顺序给出),时围城的多边形绕基准点转一圈,求刷过的面积.
易得刷过面积=大圆面积-小圆面积=π*(r大*r大-r小*r小).
怎么确定r大?即为离基准点最远的点与基准点的距离.
怎么确定r小?有可能是基准点到某个点的距离,有可能是到某两点连线的线段的距离(注意是线段).
r大非常好算,r小就麻烦一点了.我们需要考虑基准点与每一对相邻点的关系.
我们需要分类讨论.
我们设基准点为x,两个相邻点为y,z,x与y距离为a,x与z距离为b,y与z距离为c.
如果a^2+c^2<b^2,则x到线段yz的距离为a(特殊的,相等的情况也包含);
如果b^2+c^2<a^2,则x到线段yz的距离为b(特殊的,相等的情况也包含);
其他情况,则为下图:
此时,x到yz的垂线在三角形内部,那么可以用海伦公式解决,先通过公式算出三角形面积,然后乘以2除以c就行了.
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int maxn=100005; 7 const double PI=acos(-1.0); 8 int n; 9 double Mx,Mn; 10 inline int read(){ 11 int x=0,f=1; char ch=getchar(); 12 while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-f; ch=getchar();} 13 while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); 14 return x*f; 15 } 16 struct point{ 17 int x,y; 18 void re(){x=read(),y=read();} 19 }A[100005]; 20 double ds(point P,point Q){return sqrt((double)(P.x-Q.x)*(P.x-Q.x)+(double)(P.y-Q.y)*(P.y-Q.y));} 21 int main(){ 22 n=read(),A[0].re(),Mx=-1,Mn=1e18; 23 for (int i=1; i<=n; i++) A[i].re(); A[n+1]=A[1]; 24 for (int i=1; i<=n; i++){ 25 double a=ds(A[i],A[0]); 26 double b=ds(A[i+1],A[0]); 27 double c=ds(A[i],A[i+1]); 28 Mx=max(Mx,max(a,b)); 29 if (a*a+c*c<=b*b) Mn=min(Mn,a); else 30 if (b*b+c*c<=a*a) Mn=min(Mn,b); else{ 31 double p=(a+b+c)/2.0,s=sqrt(p*(p-a)*(p-b)*(p-c)); 32 Mn=min(Mn,s*2.0/c); 33 } 34 } 35 printf("%.15f",PI*(Mx*Mx-Mn*Mn)); 36 return 0; 37 }
[CodeForces - 614C] C - Peter and Snow Blower