Codeforces Peter 614 C and Snow Blower

来源:互联网 发布:linux 查看服务器编码 编辑:程序博客网 时间:2024/04/29 14:40
计算几何: 

计算一个多边形绕着圆心旋转一周所得区域的面积,通过样例就可以看出应该是是一个圆环,所以只需要找到图形上到圆心的最远点和最近点即可,最远点一定在点上,最近点可能在点上可能在边上,具体判断方法是:由于点的给出方法为顺时针或逆时针,所以只需要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;}


0 0