POINPOLY - Editorial

Consider a convex quadrilateral with corners (0,0), (2,0), (1002,2), and (1000,2). The only internal grid point is (501,1).

Or a more complicated case:


1
11
       0         0
   1000999      1001
   3001997      3002
   5001995      5002
   9999990     10000
   9997990      9998
   8994991      8995
   6991993      6992
   3991996      3992
    993999       994
     -2000        -2

which has 71 internal grid points. The first few are


994999 995
995999 996
996999 997
997999 998
998999 999
..

but they are not close to the vertices.

1 Like

Minor point: you donā€™t handle the case where two mid points are identical.

Input


1
25
75  21
66  21
55  20
45  18
36  16
28  14
21  12
15  10
10  8
6   6
3   4
1   2
0   0
1  -2
3  -4
6  -6
10 -8
15 -10
21 -12
28 -14
36 -16
45 -18
55 -20
65 -21
74 -21

gives output


70 0
70 0

This is another way to do it. It allows you to enumerate as many points as you want in O(k+n.log(M)) operations, where k is the number of points returned, and M is the maximum size of any integer coordinate.

First split the polygon into n-2 triangles (emanating from a fixed vertex).
Then for each triangle with vertices (p0, p1, p2), translate to (0, p1-p0, p2-p0), then transform
these vertices by a 2x2 matrix with integer entries and determinant 1 into the form
((0,0), (g,0), (a,b)), where b, g >0. (Could also insist 0ā‰¤a<g, but it doesnā€™t matter.)
This is OK to do, because such matrices preserve the integer grid of points. This step takes O(log(M)) operations for each of the n-2 triangles.

Then you can show that the only case there are no interior points is when (g=1 or b=1 or g=b=2) and (b|a or b|(a-g)), which is an O(1) check. You can also show that if there are some interior points then there are least b/4-1/2 of them, which means you can check each of the b horizontal lines inside the triangle and spend no more work than O(#points returned).

(You have to make a slight adjustment for counting points on the edges of the triangles, which
is allowed if they are interior to the polygon.)

1 Like

yesā€¦ right !!

Wow! How did you derive this @john_smith_3 ? Any tips on how to generate such sexy polygons? :3

Take the co-ordinates of the original sample data, and multiply by an integer 2 by 2 matrix with determinate 1.

\left( \begin{matrix} 1000 & 999999 \\\\ 1 & 1000 \end{matrix} \right) \left( \begin{matrix} 0 & 1 & 2 & 2 & 0 & -2 & -5 & -8 & -8 & -6 & -2 \\\\ 0 & 1 & 3 & 5 & 10 & 10 & 9 & 7 & 4 & 1 & 0 \end{matrix} \right)

If the original points form a convex polygon, then so do the transformed points. Internal grid points of the original polygon will transform 1-to-1 onto the internal grid points of the transformed polygon.

3 Likes

Wow!! Thats so nice to know!! Thank you @john_smith_3 !!

@john_smith_3 very clever trick !! #@

See also the comment by @alexthelemon. There he takes a possibly long thin triangle and transforms it to a nicer shape where it is easy to find the internal grid points.

@john_smith_3 :IF we consider a square,we require [4/10] = 0 points.So not an issue!

@monsij - he gave another example of convex polygon where internal points were quite far from vertices.

Hello Everyone!
The approaches used by other participants is really good and clever even at some points. However, amidst all those smart approaches, Iā€™d like to present the approach used by me(I donā€™t exactly know if it has been mentioned already because of a hefty amount of comments).So, it goes like this, Just select two random or linear non-consecutive points from the given set of points and draw a straight line between them. Count all Integral points on that line excluding the End points (Counting the integral points on a line is left as a healthy exercise for the reader) and store them in a set to avoid duplicates. An extra [log N] is just used in the set operation which too could have been avoided by choosing the the endpoints more smartly. Repeat the approach for two different pair of points to suffice for the N/10 points. I hope it helps. Please feel free to enquire more.

I like this problemā€¦ maybe it have short and fast way ā€¦ but i solved this in a very very interesting way!
ā€¦first i earn 4 chain for this: left , top , right , bottom --> each chain consist from some segment(sequence points): for each point now i must do this; for example for chain in left i must find segment that maybe! intersected with horizontal line passing from our pointā€¦ now i just need checked this really intersect or no! if no --> so point is outside polygonā€¦ if for all chains we have intersected in 4 case(if in each case exist segment and one case i mentioned(left)) we can say this point is inside polygon ā€¦ so now i used bfs from all given points(move in 4 direction and if it was outside i break this else counted and i continue next moving from this) for polygon and check above for each point and save visited point in a set to not visited more than once until we do this for all point on polygon or get ans([N/10] inside).