Advertisement
Tucancitto

Proiect AF - Poligon

Jan 2nd, 2021 (edited)
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.04 KB | None | 0 0
  1. // https://www.infoarena.ro/problema/poligon
  2. // Se citesc varfurile unui poligon si M puncte din fisier.
  3. // Determinati cate dintre cele M puncte se gasesc in planul poligonului (inclusiv pe laturile acestuia).
  4.  
  5. #include <iostream>
  6. #include <fstream>
  7. #include <algorithm>
  8. #include <vector>
  9. using namespace std;
  10.  
  11. ifstream fin("poligon.in");
  12. ofstream fout("poligon.out");
  13.  
  14. vector<int> v[100];
  15.  
  16. bool vertical;
  17. int nrVfPoligon, k, abscisa[100];
  18. double mid;
  19.  
  20. struct Punct
  21. {
  22.     int coordX, coordY;
  23. } poligon[100];
  24.  
  25. void citireVfPoligon()
  26. {
  27.     for (int i = 1; i <= nrVfPoligon; i++)
  28.     {
  29.         fin >> poligon[i].coordX >> poligon[i].coordY;
  30.         abscisa[i] = poligon[i].coordX;
  31.     }
  32. }
  33.  
  34. double eval(Punct p1, Punct p2, double m)
  35. {
  36.     return p1.coordY + ((double)p2.coordY - p1.coordY) * (m - p1.coordX) / ((double)p2.coordX - p1.coordX);
  37. }
  38.  
  39. bool comp(int coordX, int coordY)
  40. {
  41.     return eval(poligon[coordX], poligon[coordX + 1], mid) < eval(poligon[coordY], poligon[coordY + 1], mid);
  42. }
  43.  
  44. long long Determinant(Punct p1, Punct p2, Punct p3)
  45. {
  46.     //Determinant Sarrus
  47.     return 1LL * p1.coordX * p2.coordY + 1LL * p2.coordX * p3.coordY + 1LL * p3.coordX * p1.coordY
  48.         - 1LL * p1.coordX * p3.coordY - 1LL * p2.coordX * p1.coordY - 1LL * p3.coordX * p2.coordY;
  49. }
  50.  
  51. bool compare(Punct p1, Punct p2)
  52. {
  53.     if (p1.coordX == p2.coordX)
  54.         return p1.coordY < p2.coordY;
  55.     return p1.coordX < p2.coordX;
  56. }
  57.  
  58. bool OK(int i, Punct p)
  59. {
  60.     long long det;
  61.  
  62.     if (compare(poligon[i], poligon[i + 1]))
  63.         det = Determinant(poligon[i], poligon[i + 1], p);
  64.     else
  65.         det = Determinant(poligon[i + 1], poligon[i], p);
  66.  
  67.     if (det == 0)
  68.     {
  69.         vertical = true;
  70.         return 1;
  71.     }
  72.     return det > 0;
  73. }
  74.  
  75. void precompute()
  76. {
  77.     sort(abscisa + 1, abscisa + nrVfPoligon + 1);
  78.  
  79.     abscisa[0] = -1;
  80.     poligon[nrVfPoligon + 1] = poligon[1];
  81.  
  82.     for (int i = 1; i <= nrVfPoligon; i++)
  83.         if (abscisa[i] != abscisa[k])
  84.             abscisa[++k] = abscisa[i];
  85.  
  86.     abscisa[k + 1] = abscisa[k] + 100;
  87.  
  88.     for (int i = 1; i <= k; i++)
  89.     {
  90.         for (int j = 1; j <= nrVfPoligon; j++)
  91.             if ((poligon[j].coordX <= abscisa[i] && abscisa[i + 1] <= poligon[j + 1].coordX) ||
  92.                 (poligon[j + 1].coordX <= abscisa[i] && abscisa[i + 1] <= poligon[j].coordX))
  93.                 v[i].push_back(j);
  94.  
  95.         mid = ((double)abscisa[i] + (double)abscisa[i + 1]) / 2;
  96.  
  97.         sort(v[i].begin(), v[i].end(), comp);
  98.     }
  99. }
  100.  
  101. void compute(int m, int& nrIntrusi)
  102. {
  103.     for (int i = 1; i <= m; i++)
  104.     {
  105.         Punct PunctCurent = { 0 };
  106.         fin >> PunctCurent.coordX >> PunctCurent.coordY;
  107.  
  108.         int pozitie = 0, contor = -1;
  109.  
  110.         for (int i = 1 << 9; i; i >>= 1)
  111.             if (pozitie + i <= k && abscisa[pozitie + i] < PunctCurent.coordX)
  112.                 pozitie += i;
  113.  
  114.         vertical = 0;
  115.  
  116.         for (int i = 1 << 9; i; i >>= 1)
  117.             if (contor + i < v[pozitie].size() && OK(v[pozitie][i + contor], PunctCurent))
  118.                 contor += i;
  119.         contor++;
  120.         nrIntrusi += ((contor & 1) | (vertical));
  121.     }
  122. }
  123.  
  124. int main()
  125. {
  126.     int m, nrIntrusi = 0;
  127.  
  128.     fin >> nrVfPoligon >> m;
  129.     citireVfPoligon();
  130.  
  131.     precompute();
  132.     compute(m, nrIntrusi);
  133.     fout << nrIntrusi;
  134.  
  135.     fin.close();
  136.     fout.close();
  137.     return 0;
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement