#include #include #include #include #include #include #include #include using namespace std; // Define the CGAL kernel and associated types. typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_2 Point; // For 2D points. typedef CGAL::Polygon_2 Polygon_2; // For polygons. // The Parachuter class contains the method overArea. class Parachuter { public: // overArea returns: // 0 if there is an input error (polygon is self-intersecting, // has duplicate vertices, or a vertex lies on an edge), // 1 if the plane (planeX, planeY) is inside or exactly on the border // of the polygon, // 2 if the plane is outside the polygon. // // Parameters: // points: a vector of strings, each formatted as "(x,y)", representing // the vertices of the polygon in order. // planeX, planeY: the x and y coordinates of the plane. int overArea(const vector& points, int planeX, int planeY) { // Check that we have at least 3 vertices to form a polygon. if (points.size() < 3) return 0; // Vector to store the parsed vertices as CGAL points. vector vertices; // Parse each coordinate string. // Expected format: "(x,y)" where x and y are integers. for (const string& s : points) { // Minimal valid string is "(0,0)" which is 5 characters. if (s.size() < 5) return 0; // Remove the surrounding parentheses. // For example, from "(10,20)" we get "10,20". string inside = s.substr(1, s.size() - 2); // Find the position of the comma. size_t commaPos = inside.find(','); if (commaPos == string::npos) return 0; // Invalid format if no comma is found. // Extract the substring for the x coordinate. string xStr = inside.substr(0, commaPos); // Extract the substring for the y coordinate. string yStr = inside.substr(commaPos + 1); int x_val, y_val; try { // Convert the substrings to integers. x_val = stoi(xStr); y_val = stoi(yStr); } catch (...) { // If conversion fails, the input is invalid. return 0; } // Create a CGAL point using the parsed coordinates. vertices.push_back(Point(x_val, y_val)); } // Check for duplicate vertices. // A duplicate vertex means the polygon is invalid. for (size_t i = 0; i < vertices.size(); i++) { for (size_t j = i + 1; j < vertices.size(); j++) { if (vertices[i] == vertices[j]) return 0; // Duplicate vertex found. } } // Construct the polygon using the vertices in the order given. Polygon_2 poly; for (const Point& p : vertices) { poly.push_back(p); } // Check if the polygon is simple. // A non-simple polygon (i.e. one that self-intersects or has a vertex on an edge) // is considered invalid. if (!poly.is_simple()) return 0; // Create a CGAL point for the plane's location. Point planePoint(planeX, planeY); // Determine the location of the point relative to the polygon. // CGAL's bounded_side() returns: // ON_BOUNDED_SIDE if the point is inside the polygon, // ON_BOUNDARY if the point is exactly on an edge, // ON_UNBOUNDED_SIDE if the point is outside the polygon. CGAL::Bounded_side side = poly.bounded_side(planePoint); // If the point is inside or on the boundary, return 1. if (side == CGAL::ON_BOUNDED_SIDE || side == CGAL::ON_BOUNDARY) return 1; else // Otherwise, the point is outside the target area; return 2. return 2; } }; //////////////////////////// /// Example Usage/Test: /// //////////////////////////// #define UNIT_TEST 1 #ifdef UNIT_TEST #include int main(){ Parachuter parachuter; // Test 1: A valid square polygon. vector square = {"(0,0)", "(10,0)", "(10,10)", "(0,10)"}; // Test point inside the square. int res = parachuter.overArea(square, 5, 5); cout << "Test 1 (inside): " << res << endl; assert(res == 1); // Test point outside the square. res = parachuter.overArea(square, 15, 5); cout << "Test 2 (outside): " << res << endl; assert(res == 2); // Test 3: Invalid polygon (duplicate vertex). vector duplicate = {"(0,0)", "(10,0)", "(10,0)", "(0,10)"}; res = parachuter.overArea(duplicate, 5, 5); cout << "Test 3 (duplicate vertex): " << res << endl; assert(res == 0); // Test 4: Self-intersecting polygon (bow-tie shape). vector bowtie = {"(0,0)", "(10,10)", "(0,10)", "(10,0)"}; res = parachuter.overArea(bowtie, 5, 5); cout << "Test 4 (self-intersecting): " << res << endl; assert(res == 0); vector polygon1 = {"(0,0)", "(4,4)", "(0,4)", "(4,0)"}; res = parachuter.overArea(polygon1, 5, 5); cout << "Test 5 (self-intersecting): " << res << endl; assert(res == 0); cout << "All tests passed." << endl; return 0; } #else int main(){ // For a submission, only the Parachuter class is needed. return 0; } #endif