传送门:http://codeforces.com/contest/613/problem/A
计算几何:
计算一个多边形绕着圆心旋转一周所得区域的面积,通过样例就可以看出应该是是一个圆环,所以只需要找到图形上到圆心的最远点和最近点即可,最远点一定在点上,最近点可能在点上可能在边上,具体判断方法是:由于点的给出方法为顺时针或逆时针,所以只需要O(n)扫一遍环即可,利用余弦定理去判断形成的角是否为钝角,(即最近点是不是在给定的边上)如果是钝角的话那么则取两个端点的最小值,如果不是的话则利用海伦公式求高即可,海伦公式是求面积的,导出高,再设置一下精度就ok了!!
#include <bits/stdc++.h>
using namespace std;
#define PI acos(-1)
struct Node{
double x, y;
}node[100010];
double DISTANCE(int a, int b){
return sqrt((node[a].x - node[b].x) * (node[a].x - node[b].x)
+ (node[a].y - node[b].y) * (node[a].y - node[b].y));
}
int main()
{
int n;
double up, down, s;
scanf("%d%lf%lf", &n, &node[0].x, &node[0].y);
up = 0; down = 1e20;
for(int i = 1; i <= n; i++){
scanf("%lf%lf", &node[i].x, &node[i].y);
up = max(DISTANCE(i, 0), up);
}
for(int i = 1; i < n; i++){
double a = DISTANCE(0, i);
double b = DISTANCE(0, i + 1);
double c = DISTANCE(i, i + 1);
if(a*a + c*c - b*b < 0 || b*b + c*c - a*a < 0){
down = min(down, min(a, b));
}
else{
double p = (a + b + c) / 2;
down = min(down, 2 * sqrt(p * (p - a) * (p - b) * (p - c)) / c);
}
}
{
double a = DISTANCE(0, 1);
double b = DISTANCE(0, n);
double c = DISTANCE(1, n);
if(a*a + c*c - b*b < 0 || b*b + c*c - a*a < 0){
down = min(down, min(a, b));
}
else{
double p = (a + b + c) / 2;
down = min(down, 2 * sqrt(p * (p - a) * (p - b) * (p - c)) / c);
}
}
s = ((up * up) - (down * down)) * PI;
printf("%.16lf\n", s);
return 0;
}