Submission details
Task:Point in Polygon
Sender:discape
Submission time:2025-11-10 17:18:42 +0200
Language:C++ (C++20)
Status:READY
Result:ACCEPTED
Test results
testverdicttime
#1ACCEPTED0.01 sdetails
#2ACCEPTED0.02 sdetails
#3ACCEPTED0.00 sdetails
#4ACCEPTED0.00 sdetails
#5ACCEPTED0.00 sdetails
#6ACCEPTED0.00 sdetails
#7ACCEPTED0.00 sdetails
#8ACCEPTED0.00 sdetails
#9ACCEPTED0.00 sdetails
#10ACCEPTED0.00 sdetails
#11ACCEPTED0.00 sdetails
#12ACCEPTED0.00 sdetails
#13ACCEPTED0.00 sdetails
#14ACCEPTED0.00 sdetails

Code

// clang-format off
#include <bits/stdc++.h>
using namespace std;
#ifdef DO_DBG
namespace std { // these allow printing all pairs, vectors, sets and maps, recursively too
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) 
  { return os << '(' << p.first << ", " << p.second << ')'; }
template <typename T> requires (!std::is_convertible_v<T, const char*>) && ranges::range<T> && (!is_same_v<T, string>)
ostream& operator<<(ostream &os, const T &p) { os << "{ "; for (auto& x : p) os << x << ' '; os << '}'; return os; }
} // end namespace std
#define dbg(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", _dbg_out(__VA_ARGS__)
template <typename T> void _dbg_out(const T &t) { cerr << t << "]\n"; }
template <typename T, typename... Args> void _dbg_out(const T &t, const Args &...args) { cerr << t << ", "; _dbg_out(args...); }
#else
#define dbg(...)
#endif
template <typename... Args> void read(Args&... args) { ((cin >> args), ...); }
template <typename T> using v = vector<T>;
typedef long long ll; typedef long double ld; typedef v<ll> vi; typedef pair<ll, ll> pii; // this template is kactl compatible
#define ios ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin.exceptions(cin.failbit);
#define rep(i,a,b) for (ll i = a; i < b; i++)
#define rp(n) for (ll i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define sq(x) ((x)*(x))
#define d(...) ll __VA_ARGS__; read(__VA_ARGS__);
#define dv(x, n) vi x(n); for (size_t i = 0; i < n; i++) cin >> x[i];
#define even(x) ((x)%2==0)
#define odd(x) ((x)%2!=0)
#define sz(s) ((ll)s.size())
#define dist(v,it) distance(v.begin(),it)
typedef complex<ll> Pi;
typedef complex<ld> Pr;
#define X real()
#define Y imag()
#define cross(a,b) (conj(a)*(b)).imag()
// clang-format on

// is point in polygon or it's boundary
int main() {
  ios;
  d(n, m);
  v<Pi> poly(n);
  rp(n) {
    d(x, y);
    poly[i] = Pi(x, y);
  }
  while (m--) {
    d(x, y);
    Pi point = Pi(x, y);
    // we determine if the point is inside the polygon using ray-casting
    // we shoot a ray to the right and count how many edges it intersects
    // if it intersects an odd number of times, the point is inside
    bool inside = false;
    bool boudary = false;
    rep(i, 0, n) {
      Pi a = poly[i] - point;
      Pi b = poly[(i + 1) % n] - point;
      // a and b are the endpoints of the edge relative to point
      // if the cross product is 0, then the point is on the line ab
      // then we just need to check if the point is between a and b
      // by checking that the signs of the x and y coordinates are opposite,
      // which is required if the point goes through the center
      if (cross(a, b) == 0 && (a.X * b.X <= 0) && (a.Y * b.Y <= 0)) {
        boudary = true;
        break;
      }
      // if the ray from the center to the right intersects the edge ab,
      // a and b must be on opposite sides of the x axis
      if (a.Y > b.Y)
        swap(a, b);
      // and we also check that the edge a b is on the right side of the point
      // (center) which is true when the cross product is positive
      if (a.Y <= 0 && b.Y > 0 && cross(a, b) > 0)
        inside = !inside;
    }
    if (boudary)
      cout << "BOUNDARY\n";
    else if (inside)
      cout << "INSIDE\n";
    else
      cout << "OUTSIDE\n";
  }
}

Test details

Test 1

Verdict: ACCEPTED

input
100 1000
-7 -19
91 77
100 100
64 60
...

correct output
INSIDE
OUTSIDE
INSIDE
INSIDE
INSIDE
...

user output
INSIDE
OUTSIDE
INSIDE
INSIDE
INSIDE
...

Test 2

Verdict: ACCEPTED

input
1000 1000
365625896 -113418831
278762563 38777445
250367343 -96991975
175866909 -129766978
...

correct output
OUTSIDE
OUTSIDE
INSIDE
OUTSIDE
OUTSIDE
...

user output
OUTSIDE
OUTSIDE
INSIDE
OUTSIDE
OUTSIDE
...

Test 3

Verdict: ACCEPTED

input
4 1
1 5
5 5
5 1
1 1
...

correct output
INSIDE

user output
INSIDE

Test 4

Verdict: ACCEPTED

input
4 1
1 5
5 5
5 1
1 1
...

correct output
OUTSIDE

user output
OUTSIDE

Test 5

Verdict: ACCEPTED

input
4 1
1 100
2 50
1 20
0 50
...

correct output
INSIDE

user output
INSIDE

Test 6

Verdict: ACCEPTED

input
8 1
0 0
0 2
1 1
2 2
...

correct output
INSIDE

user output
INSIDE

Test 7

Verdict: ACCEPTED

input
4 4
0 0
3 0
3 4
0 4
...

correct output
INSIDE
BOUNDARY
OUTSIDE
BOUNDARY

user output
INSIDE
BOUNDARY
OUTSIDE
BOUNDARY

Test 8

Verdict: ACCEPTED

input
6 1
0 0
0 2
3 1
2 2
...

correct output
INSIDE

user output
INSIDE

Test 9

Verdict: ACCEPTED

input
3 1
0 0
1 1000000000
-3 0
1 1

correct output
OUTSIDE

user output
OUTSIDE

Test 10

Verdict: ACCEPTED

input
3 1
-100000 0
-1000000000 -999999999
1000000000 1000000000
0 0

correct output
OUTSIDE

user output
OUTSIDE

Test 11

Verdict: ACCEPTED

input
3 1
-100000 0
-999999999 -1000000000
1000 1000
0 0

correct output
INSIDE

user output
INSIDE

Test 12

Verdict: ACCEPTED

input
4 1
-4 1
-6 1
-6 -1
-4 -1
...

correct output
INSIDE

user output
INSIDE

Test 13

Verdict: ACCEPTED

input
3 1
0 10
0 -10
10 0
1 0

correct output
INSIDE

user output
INSIDE

Test 14

Verdict: ACCEPTED

input
3 1000
-536621709 -536621709
955833081 955833081
-1 1
-439278425 -439278425
...

correct output
BOUNDARY
BOUNDARY
BOUNDARY
BOUNDARY
BOUNDARY
...

user output
BOUNDARY
BOUNDARY
BOUNDARY
BOUNDARY
BOUNDARY
...