题目描述:http://poj.org/problem?id=1265
解题思路:
求一个顶点都在整数点上的多边形的面积。 题目中已经提示了多边形的面积A、多边形内的格点I与多边形边上的整点数E存在特殊的关系。然后在纸上枚举几个多边形算一算就能发现A = 0.5E + I - 1。这实际上就是pick公式。具体证明就不累赘了。
面积A用叉积算就行了。算每条边上整点的个数时,假设一条边从(x, y)到(px, py),令dx = fabs(x-px),dy = fabs(y-dy),那么整点的个数就是gcd(dx, dy)。
证明:我们可以把斜边均分成n个小三角形的斜边相连,且斜边的端点在整点上,那么斜边上整点的个数就是1+每个三角形斜边上整点的个数*n。(不算每条边的起始点,避免重复计算)
因为斜边的端点是整点且均分大边,所以n是dx的约数,同理n是dy的约数。所以n是(dx, dy)的公约数。n是gcd(dx, dy)时,小三角形的直角边长为(dx/n, dy/n)=(tx, ty)。由gcd的性质可得tx, ty互质。这样的三角形斜边上除了端点之外不可能有整点。因为不存在n>1同时为tx和ty的约数,所以小。
所以一条斜边上整点的个数就是n+1(加上起始点),即gcd(dx, dy)+1。
/*
* 2014.11.10
* Problem: 1265
* Memory: 180K Time: 0MS
* Language: C++ Result: Accepted
*/
#include "algorithm"
#include "cmath"
#include "iostream"
#define EPS 1e-8
#define MAXM 107
using namespace std;
void swap(int &a, int &b) {
int t = a; a = b; b = a;
}
int gcd(int a, int b) {
return (b>0)? gcd(b, a%b):a;
}
int main() {
int t; scanf("%d", &t);
int m;
int I, E;
double A;
int x, y, px, py, dx, dy;
for(int ts=1; ts<=t; ts++) {
I = E = A = x = y = px = py = 0;
scanf("%d", &m);
while (m--) {
scanf("%d %d", &dx, &dy);
x = px+dx; y = py+dy;
E += gcd(abs(dx), abs(dy));
A += 0.5*(px*y-py*x);
px = x; py = y;
}
A = fabs(A);
I = A + 1 - 0.5*E;
printf("Scenario #%d:\n%d %d %.1lf\n\n", ts, I, E, A);
}
return 0;
}