和POJ 1654类似,利用格点的性质和给的点的连续性即可。
多边形的面积:首先多边形不确定凹凸,其次多边形的点很多,所以这道题就不能用我们平常的想法去根据点计算多边形的面积。通过观察可以发现这道题有一个比较好的地方,那就是多边形的边已经按次序给出,并且保证没有任何相邻的两点和别的边构成相交的情况,而且最终一定会走回原点构成多边形,所以可以根据叉积的性质去求。|a×b|=|a|*|b|*sinθ,将叉积除以2正好就是三角形的面积,由于题目中答案一定是0.5的整数倍,所以可以先算两倍的面积最后在进行判断。
多边形的边经过的格点:发现很容易得出格点数等于每条边的gcd(dx,dy)的和。
多边形包含的格点:可以通过pick定理求出:内含的格点=(2倍的面积-边上的格点数的和+2)/2。
代码如下:
#include<stdio.h>
int p[150][2];
int square(int p1[],int p2[])
{
return p1[0]*p2[1]-p1[1]*p2[0];
}
int abs(int n)
{
if(n<0)
return -n;
return n;
}
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int main()
{
int dx,dy,t,cas=1,m,i;
scanf("%d",&t);
while(t--)
{
scanf("%d",&m);
p[0][0]=p[0][1]=0;
int s=0,e=0;
for(i=0;i<m;i++)
{
scanf("%d %d",&dx,&dy);
p[i+1][0]=p[i][0]+dx;
p[i+1][1]=p[i][1]+dy;
e+=gcd(abs(dx),abs(dy)); //算边上的格点数
s+=square(p[i+1],p[i]); //算面积
}
s=abs(s);
i=(s-e+2)/2; //pick定理
double ss=s;
printf("Scenario #%d:\n",cas++);
printf("%d %d %.1f\n\n",i,e,ss/2);
}
return 0;
}