mobilna_mreza

Mobilni operator je na karti ucrtao oblast koju pokriva novi toranj. Granica oblasti je opisana poligonom sa \(n\) temena. Na istoj karti obeležene su pozicije \(m\) baznih stanica.

Za svaku baznu stanicu poznata je i cena njenog održavanja. Ako se stanica nalazi unutar oblasti pokrivanja, trošak je opravdan. Ako se stanica nalazi izvan oblasti, trošak se smatra nepotrebnim. Kako bi se smanjili troškovi, operater želi da sve nepokrivene stanice ugasi. Potrebno je izračunati ukupnu cenu održavanja pokrivenih stanica. Stanica koja leži tačno na granici oblasti smatra se pokrivenom.

Opis ulaza

Sa standardnog ulaza se unose vrednosti \(n\) i \(m\). Nakon toga se u narednih \(n\) linija unose po \(2\) realne vrednosti \(x\) i \(y\) koje predstavljaju tačke oblasti pokrivanja ucrtane na karti. U narednih \(m\) linija se unose po \(3\) vrednosti, 2 realne koje predstavljaju koordinate bazne stanice i jedna celobrojna koja predstavlja cenu održavanja stanice.

Opis izlaza

Na standardni izlaz ispisati cenu održavanja svih pokrivenih stanica.

Primer

Ulaz

5 4 0 0 4 0 5 2 2 4 0 2 1 1 100 4.5 1.5 200 2 2 150 -1 3 300

Izlaz

450

Rešenje

Opis glavnog rešenja

U ovom bloku se opisuje glavno rešenje zadatka.

#include <iostream>
#include <vector>
#include <cmath>

#define EPS 1.0E-9

using namespace std;

struct Point {
    double x;
    double y;
    int price;
};

bool ray_intersect(const Point& A, const Point &B, Point P)
{
    if (P.y == A.y || P.y == B.y) {
        P.y += EPS;
    }

    if (P.y < A.y || P.y > B.y) {
        return false;
    }

    if (P.x > max(A.x, B.x)) {
        return false;
    }

    if (P.x < min(A.x, B.x)) {
        return true;
    }

    const auto k_AB = (B.y - A.y) / (B.x - A.x);
    const auto k_AP = (P.y - A.y) / (P.x - A.x);

    return k_AP >= k_AB;
}

bool ray_casting(const vector<Point> &poly, const Point &P)
{
    int count = 0;

    for (int i = 0; i < poly.size() - 1; i++) {
        const auto &A = poly[i];
        const auto &B = poly[i + 1];

        if (A.y < B.y) {
            if (ray_intersect(A, B, P)) {
                count++;
            }
        } else {
            if (ray_intersect(B, A, P)) {
                count++;
            }
        }
    }

    return count % 2;
}

int main()
{
    int n, m; cin >> n >> m;

    vector<Point> poly(n + 1);
    for (int i = 0; i < n; i++) {
        cin >> poly[i].x >> poly[i].y;
    }
    poly[n] = poly[0];

    vector<Point> P(m);
    for (int i = 0; i < m; i++) {
        cin >> P[i].x >> P[i].y >> P[i].price;
    }

    int total_price = 0;
    for (int i = 0; i < m; i++) {
        if (ray_casting(poly, P[i])) {
            total_price += P[i].price;
        }
    }

    cout << total_price << endl;

    return 0;
}