Codeforces Round #339 (Div. 2)C. Peter and Snow Blower(简单几何)

题意:给出一个圆心,圆心连接一根线,线的另一端是一个多边形,现在将多边形绕着圆心旋转一圈,求扫过的面积。

思路:离圆心最远的点必然是某一个顶点,但是离圆心最近的距离不一定在顶点上,可能是某一边上的某一点。

根据该三角形是否为钝角三角形判断,如果是,则选取两个顶点到圆心最近的距离作为最小距离,否则计算该三角形的高作为最小距离。

计算方式可以根据海伦公式求出面积,然后利用三角形面积公式H=2*s/d得到三角形的高

最后的结果即为π(R*R-r*r);

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;

typedef __int64 ll;
const double pi=acos(-1.0);
const int INF=0x3f3f3f3f;
const int maxn=100005;
int n;

struct Point{
	double x,y;
}point[maxn];

double getDistance(int a,int b){//计算两点间距离
	return sqrt((point[a].x-point[b].x)*(point[a].x-point[b].x)+(point[a].y-point[b].y)*(point[a].y-point[b].y));
}

double getMin(int a,int b,int c){
	double d1=getDistance(a,b);
	double d2=getDistance(a,c);
	double d3=getDistance(b,c);
	if(d1*d1+d2*d2-d3*d3<0||d1*d1+d3*d3-d2*d2<0)//如果是钝角,则返回两端点到圆心最近距离
		return min(d2,d3);
	else{
		double p=(d1+d2+d3)/2;//计算半周长
		double s=sqrt(p*(p-d1)*(p-d2)*(p-d3));//海伦公式计算三角形面积
		return 2*s/d1;//计算ab所在边的高H
	}
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
#endif
	while(~scanf("%d%lf%lf",&n,&point[0].x,&point[0].y)){
		double maxR=-INF,minR=INF;
		for(int i=1;i<=n;i++){//离圆心最远的点必然是某一个定点
			scanf("%lf%lf",&point[i].x,&point[i].y);
			double dis=getDistance(i,0);
			if(dis>maxR) maxR=dis;
		}
		point[n+1]=point[1];
		for(int i=1;i<=n;i++){//离圆心最短的点可能是边上某一点到圆心的距离
			double dis=getMin(i,i+1,0);
			if(dis<minR) minR=dis;
		}
		double res=pi*(maxR*maxR-minR*minR);
		printf("%lf\n",res);
	}
	return 0;
}


你可能感兴趣的:(Codeforces Round #339 (Div. 2)C. Peter and Snow Blower(简单几何))