题目传送门:https://codeforces.com/problemset/problem/614/C
题目大意:求一个多边形绕他外面一个点转扫过的面积。
mmp比赛时看错题了,以为那个点可以在图形内,浪费了半个钟。
思路:S=PI*(点到图形最远距离^2 - 点到图形最近距离^2),点到图形最远距离即点到图中的最远的点的距离,最近距离可能是点到点,也可能是点到边,比赛时忘了点到边的情况。算点到边距离可以套海伦公式直接算,我是用点到线距离手工算的。
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int M=1000000+10;
const double pi=acos(-1),eps=1e-10;
int n;
double u,v,maxd=-1,mind=-1,x[M],y[M];
int main()
{
scanf("%d%lf%lf",&n,&u,&v);
for(int i=0;i<n;i++) scanf("%lf%lf",&x[i],&y[i]);
for(int i=0;i<n;i++){
double A=(y[i]-y[(i+1)%n]),B=(x[(i+1)%n]-x[i]),c=x[i]*y[(i+1)%n]-x[(i+1)%n]*y[i];
double dis=(x[i]-u)*(x[i]-u)+(y[i]-v)*(y[i]-v),dis1=abs(A*u+B*v+c)/sqrt(A*A+B*B);
double d=A*v-B*u;
double xx=-(A*c+B*d)/(A*A+B*B);
maxd=max(maxd,dis);
if(xx<=max(x[i],x[(i+1)%n])+eps && xx>=min(x[i],x[(i+1)%n])-eps)//垂足横坐标在相邻两点之间时点到线距离比点到点短
dis=min(dis,dis1*dis1);
mind=mind==-1?dis:min(dis,mind);
}
printf("%.10f",pi*(maxd-mind));
return 0;
}