[UVA][Pick] 10088 - Trees on My Island
Problem D
Trees on My Island
Input: standard input
Output: standard output
I have bought an island where I want to plant trees in rows and columns. So, the trees will form a rectangular grid and each of them can be thought of having integer coordinates by taking a suitable grid point as the origin.
Figure: A sample of my island
But, the problem is that the island itself is not rectangular. So, I have identified a simple polygonal area inside the island with vertices on the grid points and have decided to plant trees on grid points lying strictly inside the polygon.
Now, I seek your help for calculating the number of trees that can be planted on my island.
Input
The input file may contain multiple test cases. Each test case begins with a line containing an integer N (3 <= N <= 1,000) identifying the number of vertices of the polygon. The next N lines contain the vertices of the polygon either in clockwise or in anti-clockwise direction. Each of these N lines contains two integers identifying the x and y-coordinates of a vertex. You may assume that none of the coordinates will be larger than 1,000,000 in absolute values.
A test case containing a zero for N in the first line terminates the input.
Output
For each test case in the input print a line containing the number of trees that can be planted inside the polygon.
Sample Input
123 1
6 3
9 2
8 4
9 6
9 9
8 9
6 5
5 8
4 4
3 5
1 3
12
1000 1000
2000 1000
4000 2000
6000 1000
8000 3000
8000 8000
7000 8000
5000 4000
4000 5000
3000 4000
3000 5000
1000 3000
0
Sample Output
2125990001
What we see is often what we look for.
當頂點座標都是整數時,計算多邊形內部的整數點個數可以使用 Pick's theorem
A = i + b/2 -1
A : 多邊形面積, b : 邊上的整數點個數, i : 內部整數點個數
#include <stdio.h>
#include <stdlib.h>
struct Pt {
long long x, y;
};
long long gcd(long long x, long long y) {
if(x == 0) return y;
if(y == 0) return x;
long long t;
while(x%y)
t = x, x = y, y = t%y;
return y;
}
int main() {
int n, i;
Pt D[1005];
while(scanf("%d", &n) == 1 && n) {
for(i = 0; i < n; i++)
scanf("%lld %lld", &D[i].x, &D[i].y);
D[n] = D[0];
long long area = 0, b = 0;
for(i = 0; i < n; i++)
area += (D[i].x*D[i+1].y) - (D[i].y*D[i+1].x);
if(area < 0) area = -area;
for(i = 0; i < n; i++)
b += gcd(abs(D[i].x-D[i+1].x), abs(D[i].y-D[i+1].y))-1;
b += n;
// A = i + b/2 - 1
printf("%lld\n", (area + 2 - b) / 2);
}
return 0;
}