<span style="font-family: Arial, Helvetica, sans-serif;"></span><pre name="code" class="cpp"><span style="font-family: Arial, Helvetica, sans-serif;">pick 定理: S = a + b /2 - 1</span>
其中,S 为格点多边形面积,a 为多边形内部整点数,b 为多边形边上整点数。
某条边(A,B)上的整点数 = gcd (|xA - xB|, |yA - yB|) (不包括 A 点)
<span style="font-family: Arial, Helvetica, sans-serif;">#include <cstdio></span>
#include <cstring>
#include <cmath>
using namespace std;
struct Point
{
int x,y;
Point(){}
Point(double _x,double _y)
{
x = _x;y = _y;
}
//向量
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
//叉积
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
//点积
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
};
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int main()
{
int t;
scanf("%d", &t);
for (int ca = 1; ca <= t; ca++) {
Point cur(0,0), next;
int n;
int area = 0, onedge = 0, inside = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
int dx, dy;
scanf("%d%d", &dx, &dy);
next.x = cur.x + dx;
next.y = cur.y + dy;
area += cur ^ next;
onedge += gcd(abs(cur.x-next.x), abs(cur.y-next.y));
cur = next;
}
area += cur ^ Point(0,0);
onedge += gcd(abs(cur.x), abs(cur.y));
inside = (area - onedge + 2) / 2;
printf("Scenario #%d:\n%d %d %.1lf\n\n", ca, inside, onedge, area / 2.0);
}
return 0;
}