这题考了个求多边形面积,考了个线段相交。
多边形面积嘛,众所周知,求每条边跟原点形成的三角形有向面积相加就行了。
有向面积求和这个事吧,不仅适用于规则的多边形,还适用于扇形神马的。表面上看起来是废话,不动手去实践一下还真不敢确信。
比如今年金华网络赛那道求多边形与圆的面积交的题,就是临场发挥蒙出来的。
吐槽一下,线段相交真的真的真的很恶心,函数一大堆,代码还那么长。。女人的裹脚布一样。。
#include<stdio.h> #include<math.h> #define eps 1e-6 struct p{ double x,y; }pt[1010]; int n; double det(double x1,double y1,double x2,double y2){ return x1*y2-x2*y1; } double cross(p a,p b,p c){ return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y); } int dblcmp(double d){ if(fabs(d)<eps) return 0; return d>0?1:-1; } int xycmp(double xy,double mini,double maxi){ return dblcmp(xy-mini)*dblcmp(xy-maxi); } int btncmp(p a,p b,p c){ if(fabs(b.x-c.x)>fabs(b.y-c.y)) return xycmp(a.x,fmin(b.x,c.x),fmax(b.x,c.x)); else return xycmp(a.y,fmin(b.y,c.y),fmax(b.y,c.y)); } int segcross(p a,p b,p c,p d){ int d1,d2,d3,d4; d1=dblcmp(cross(a,b,c)); d2=dblcmp(cross(a,b,d)); d3=dblcmp(cross(c,d,a)); d4=dblcmp(cross(c,d,b)); if((d1^d2)==-2&&(d3^d4)==-2) return 1; else return d1==0&&btncmp(c,a,b)<=0 ||d2==0&&btncmp(d,a,b)<=0 ||d3==0&&btncmp(a,c,d)<=0 ||d4==0&&btncmp(b,c,d)<=0; } int judcross(){ int i,j; for(i=0;i<n-2;i++) for(j=i+2;j<n;j++) if(segcross(pt[i],pt[i+1],pt[j],pt[j+1])){ if(i==0&&j==n-1) ; else return 1; } return 0; } int main(){ int i,j,cs=1; double sum; p p0; p0.x=p0.y=0; while(~scanf("%d",&n)&&n){ if(cs>1) printf("\n"); printf("Figure %d: ",cs++); for(i=0;i<n;i++) scanf("%lf%lf",&pt[i].x,&pt[i].y); pt[n].x=pt[0].x; pt[n].y=pt[0].y; if(n<3||judcross()){ printf("Impossible\n"); continue; } sum=0; for(i=0;i<n;i++) sum+=cross(p0,pt[i],pt[i+1]); sum=fabs(sum)*0.5; printf("%.2lf\n",sum); } return 0; }