TAKMIČENJA IZ PROGRAMIRANJA


Sva pitanja, predloge ili primedbe u vezi sa takmičenjima iz programiranja možete slati na e-mail:

tak.prog@gmail.com

U toku perioda za žalbe, sve žalbe možete slati na ovaj isti e-mail.

poljane.cpp    2,033 b      izvorni kod rešenja
poljane.tests.rar    7,943,021 b      test primeri

zadatak: Poljane

Đurica putuje vozom kroz Vojvodinu i uživa razgledajući predivne poljane. Tokom putovanja on često (i ovaj put) fiksira položaj glave i razgleda, ne bi li bio siguran da neće propustiti ni jedan metar prelepog prizora, kao i da će svakom pokloniti isto vremena. Iz tih razloga, položaj njegove glave ostaje fiksiran tokom putovanja. Poljane su oblika pravougaonika, sa stranicama paralelnim ili normalnim na prugu.

Radi lakšeg opisa, pretpostavićemo da se pruga nalazi na x-osi, a poljane u prvom kvadrantu koordinatnog sistema. Svaka poljana je predstavljena svojim donjim-levim i gornjim-desnim temenom. Đuricin pogled ćemo predstaviti polupravom koja menja svoju početnu tačku duž x-ose u pozitivnom smeru. Nagib poluprave na x-osu je izražen u stepenima, a ima vrednost alfa.

Nakon svog putovanja, Đurica se zamislio i zapitao koji je najveći broj poljana koje je on u nekom momentu posmatrao, tj. presekao pogledom. Pošto ćete vi dobiti opis poljana i ugao nagiba alfa, pomozite Đurici i izračunajte koji je najveći broj poljana u nekom momentu koje je Đurica presekao pogledom.

Ulaz:

(Ulazni podaci se nalaze u datoteci poljane.in) U prvom redu nalaze se prirodni brojevi n (1 ≤ n ≤ 100.000) i alfa (1 ≤ alfa ≤ 90), koji predstav aju broj po ana i ugao nagiba Đuricinog pogleda u stepenima, redom. U narednih n redova su data po četiri prirodna broja x1, y1, x2, y2 (1 ≤ x1 < x2 ≤ 100.000, 1 ≤ y1 < y2 ≤ 100.000) koji označavaju donje-levo i gornje-desno teme poljana, redom - u i-tom redu koordinate za i-tu poljanu.

Izlaz:

(Izlazne podatke upisati u datoteku poljane.out) U prvom i jedinom redu ispisati jedan ceo broj koji predstavlja najveći broj poljana koje je Đurica u nekom momentu video.

Primer:

poljane.in      poljane.out
4 45
3 1 5 2
7 2 8 3
7 4 9 5
2 3 5 5
        
3

Objašnjenje.

Kada se Đurica bude nalazio na koordinati 4 x-ose, videće prve tri poljane date na ulazu. Poljani pripada i rub pravougaonika koji je ograničava. Dovoljno je posmatrati samo jednu tačku, na primer teme, poljane da se smatralo da pogled preseca poljanu.

fajl: poljane.cpp
#include <iostream>
#include <cstdio>
#include <fstream>
#include <vector>
#include <cmath>
#define ffor(_a,_f,_t) for(int _a=(_f),__t=(_t);_a<__t;_a++)
#define all(_v) (_v).begin() , (_v).end()
#define sz size()
#define pb push_back
#define SET(__set, val) memset(__set, val, sizeof(__set))
#define FOR(__i, __n) ffor (__i, 0, __n)

using namespace std;

const int MAXN = 100000;
const double PI2 = acos(0.0);

int xx1, yy1, xx2, yy2, alpha;

struct myt{
  double pos;
  bool start;
  
  myt(){
  }
  
  myt(double _pos, bool _start){
    pos = _pos;
    start = _start;
  }
  
  friend bool operator <(const myt &a, const myt &b){
    if (fabs(a.pos - b.pos) > 1e-9)
      return a.pos < b.pos;
      
    return a.start && !b.start;
  }
};

myt points[MAXN << 1];

/*
  Za datu tacku (a, b), zelimo da za pravu
  sa nagibom alpha koja sadrzi tacku (a, b)
  nadjemo mesto presecanja na x-osi.
*/
double calc(double a, double b){
  if (alpha == 90)
    return a;
  
  // 90 : PI2 = alpha : rad - pretvaramo u radijane
  double rad = PI2 * alpha / 90.0;
  
  // b / c = tg alpha; b i c su stranice
  // pravouglog trougla kojeg posmatramo,
  // tj. onog koji ima jedan ugao alpha,
  // ugao naspram stranice a. Resenje ce
  // biti a - c
  double c = b / tan(rad);
  return a - c;
}

int main(){
  char filein[16] = "poljane.in";
  char fileout[16] = "poljane.sol";
  FILE *fin;
  FILE *fout;
  
    
  fin = fopen(filein, "r");
  fout = fopen(fileout, "w");
  
  int n;
  fscanf(fin, "%d %d", &n, &alpha);
  FOR (i, n){
    fscanf(fin, "%d %d %d %d", &xx1, &yy2, &xx2, &yy1);
    points[i << 1] = myt(calc(xx1, yy1), true);
    points[(i << 1) + 1] = myt(calc(xx2, yy2), false);
  }
  sort(points, points + (n << 1));
  
  int ret = 0, cnt = 0;
  FOR (i, n << 1){
    if (points[i].start)
      cnt++;
    else
      cnt--;
      
    ret >?= cnt;
  }
  
  fprintf(fout, "%d\n", ret);

  fclose(fin);
  fclose(fout);
  
  return 0;
}