2013-07-05 11:18:46Morris

[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

12
3 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

21
25990001
____________________________________________________________________________________________ Rezaul Alam Chowdhury


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;
}