处理何种问题:给定顶点坐标均是整点的任意多边形,
S(面积) = a(内部格点数目) + b(边上格点数目)/2 - 1 。
如图所示:
S=14.50
a=11
b=9(最上方的边内有一整数点)
性能:时间复杂度为 O(n)。
原理:皮克定理我在这里就不贴证明资料了。对于多边形面积的求法用的是叉积求法。在这里重点说一下--b(边上格点数目)的求法:对于两个顶点构成的线段所覆盖到的整数顶点的个数=GCD(dx,dy)+1。(dx为横坐标之差,dy为纵坐标之差)
实现步骤:叉乘求面积+上述方法求b
备注:因为求的是一个封闭图形的b数目,所以可以不用+1了;必须逆时针输入顶点。
输入样例解释:
8 //顶点个数
2 0 //顶点坐标
4 1
3 2
2 4
0 4
-2 3
0 2
-2 1
输出样例解释:
S=14.50 //多边形面积
a=11 //多边形内部格点数目
b=9 //多边形边上格点数目
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<cmath>
#include<string>
using namespace std;
struct Point
{
double x,y;
};
Point arr[10010];
int GCD(int a,int b)//有些c++的环境是不支持__gcd();
{
int temp;
while(a!=0)
{
temp=a;
a=b%a;
b=temp;
}
return b;
}
int main()
{
int n,x,y,sum_a,sum_b;
double area=0,x1,y1,x2,y2;
while(~scanf("%d",&n))
{
sum_a=sum_b=area=0;
for(int i=0;i<n;++i)
scanf("%lf%lf",&arr[i].x,&arr[i].y);
for(int i=1;i<n;++i)
{
x=abs(arr[i].x-arr[i-1].x);
y=abs(arr[i].y-arr[i-1].y);
sum_b+=GCD(x,y); //因为求的是一个封闭图形的b数目,所以可以不用+1了
}
x=abs(arr[0].x-arr[n-1].x);
y=abs(arr[0].y-arr[n-1].y);
sum_b+=GCD(x,y);
for(int i=0;i<n-1;++i)
{
x1=arr[i].x-arr[0].x;
y1=arr[i].y-arr[0].y;
x2=arr[i+1].x-arr[0].x;
y2=arr[i+1].y-arr[0].y;
area+=(x1*y2-x2*y1)/2;
}
sum_a=area-sum_b*1.0/2+1;
printf("S=%.2lf\n",area);
printf("a=%d\n",sum_a);
printf("b=%d\n",sum_b);
}
return 0;
}