第一行三个整数,n,sx,sy。n表示多边形的顶点数。
接下来n行每行俩整数,分别表示多边形一个顶点的横纵坐标。
(顶点是按照顺时针或者逆时针顺序给出的,并且所有点的坐标绝对值<=,保证不存在共线的三个顶点)
一个整数,表示面积四舍五入为整数的结果。
3 0 0 0 1 -1 2 1 2
13
这道题主要是求最小半径以及最大半径
易证明最大半径mx一定在顶点位置
而最小半径也可能在两点的直线上
明白这一点后代码就很好实现了 不过要注意精度问题 今天似乎大爷们都被精度卡了 2333
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define LL long long using namespace std; const int M=155; const double P=3.141592653589793238462643383279502884; LL read(){ LL ans=0,f=1,c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();} while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();} return ans*f; } double mx,mn=1e15; double k1,k2,b,L,mxx,mnx,nx; LL x[M],y[M],n,sx,sy; int main() { n=read(); sx=read(); sy=read(); for(int i=1;i<=n;i++){ x[i]=read()-sx; y[i]=read()-sy; L=1.0*(fabs(x[i])*fabs(x[i])+fabs(y[i])*fabs(y[i])); mx=max(mx,L); mn=min(mn,L); } for(int i=1;i<=n;i++){ int j=i+1<=n?i+1:1; if(x[i]==x[j]){ if((y[i]>0&&y[j]<0)||(y[i]<0&&y[j]>0)) mn=min(mn,(double)x[i]*x[j]); continue; } mxx=max(x[i],x[j]); mnx=min(x[i],x[j]); if(y[i]==y[j]){ if(mxx>0&&mnx<0) mn=min(mn,(double)y[i]*y[j]); continue; } k1=(double)(y[i]-y[j])/(x[i]-x[j]); b=(double) y[i]-k1*x[i]; k2=-1.0/k1; nx=b/(k2-k1); if(nx>mxx||nx<mnx) continue; L=b/sqrt(k1*k1+1); mn=min(mn,L*L); } printf("%lld",(long long)(P*(mx-mn)+0.5)); return 0; }
原文:http://www.cnblogs.com/lyzuikeai/p/7191979.html