Input
输入数据包含多个测试实例,每个测试实例占一行,每行的开始是一个整数n(3<=n<=100),它表示多边形的边数(当然也是顶点数),然后是按照逆时针顺序给出的n个顶点的坐标(x1, y1, x2, y2... xn, yn),为了简化问题,这里的所有坐标都用整数表示。
输入数据中所有的整数都在32位整数范围内,n=0表示数据的结束,不做处理。
Output
对于每个测试实例,请输出对应的多边形面积,结果精确到小数点后一位小数。
每个实例的输出占一行。
思路:用一个最小的矩形框住目标多边形,矩形的长由min x和max x决定,宽由min y和min x决定.然后用矩形面积减去一个个的三角形以及余下的矩形(例如:当最左边和最下面的点之间有点,那个点会和外面的大矩形的边构造成一个矩形)
我简略画了个图:
下面的代码中有比较详细的注释了
#include<stdio.h>
#include<string.h>
#include<math.h>
int main(){
int n;float x[105],y[105];
while(scanf("%d",&n)&&n)
{ float sum=0,s=0;
int i=0,k=n,MINx=10000,MAXx=-10000,MINy=10000,MAXy=-10000;
int maxx,minx,maxy,miny;
while(n--)
{scanf("%f%f",&x[i],&y[i]);
if(x[i]>MAXx){maxx=i;MAXx=x[i];} //最后可知例如:最右边的坐标就是(x[maxx],y[maxx])
if(x[i]<MINx){minx=i;MINx=x[i];} // 最上面的坐标就是(x[maxy],y[maxy])
if(y[i]>MAXy){maxy=i;MAXy=y[i];} // 最左面的坐标就是(x[minx],y[minx])
if(y[i]<MINy){miny=i;MINy=y[i];} // 最下面的坐标就是(x[miny],y[miny])
i++;
}
sum=(y[maxy]-y[miny])*(x[maxx]-x[minx]);
for(int j=0;j<k;j++)
{ //因为最后一个坐标和第一个坐标相连,所以要在(j+1)后面加上%k
s+=fabs((x[j]-x[(j+1)%k])*(y[j]-y[(j+1)%k]))/2;//计算每两个坐标间的三角形面积
// 1.左下角和右上角的计算都要拿下一个坐标即j+1去判断,
// 如果下一个的坐标不在该开区间2和4内,则不会出现矩形
//先计算左下角的矩形面积,只有当最左边的点和最下面的点中间有点才会出现矩形。
if(y[(j+1)%k]<y[minx]&&y[(j+1)%k]>y[miny]&&x[(j+1)%k]<x[miny])
s+=fabs((x[j]-x[(j+1)%k])*(y[(j+1)%k]-y[miny]));
else if(y[(j+1)%k]>y[maxx]&&y[(j+1)%k]<y[maxy]&&x[(j+1)%k]>x[maxy]) //计算右上角
s+=fabs((x[j]- x[(j+1)%k])*(y[(j+1)%k]-y[maxy]));
//2.左上角和右下角的计算就拿当前坐标即j去判断,只要该坐标在开区间1和3内,就会出现矩形
else if(y[j]>y[minx]&&y[j]<y[maxy]&&x[j]<x[maxy]) //计算左上角
s+=fabs((x[j]-x[(j+1)%k])*(y[j]-y[maxy]));
else if(y[j]<y[maxx]&&y[j]>y[miny]&&x[j]>x[miny]) //计算右下角
s+=fabs((x[j]-x[(j+1)%k])*(y[j]-y[miny]));
}
printf("%.1f\n",sum-s);
}
return 0;
}