/**Aici ai sursa mea de la problema Raza ONI VII 2022 cu explicatii. .
O poti citi si cand ne vedem iti explic daca e ceva ce nu ai inteles. ~ George */
#include
using namespace std;
ifstream cin("raza.in");
ofstream cout("raza.out");
/**
Patratul de latura razei ce incepe din coord (xA,yA).
A B
-------------
| |
| |
| |
| |
-------------
D C
*/
int Sec[100001];
int main()
{
int cerinta , n ,s ;
cin>>cerinta>>n>>s;
if(cerinta==1)
{
int cnt = 0;
for(int i = 1;i<=n;i++)
{
//cout<<"Roverul "<>l>>c>>r;
/**Verificam daca AB se intersecteaza cu diagonala.
Diagonala in cazul nostru se afla pe pozitia unde l=c iar c creste cu raza - 1.
Se intersecteaza daca in poz intitiala e inaintea diagonalei sau pe ea (c<=l).
Iar pozitia finala a coloanei este mai mare sau egala cu coord liniei. */
if(c<=l&&c+r - 1>=l)
{
intersect = true;
// cout<<"AB\n";
}
/**Verificam daca AD se intersecteaza cu diagonala. Linia creste cu raza.
Se poate intersecta daca in poz intitiala este deasupra diagonalei si coborand
se intersecteaza cu aceasta. */
if(l<=c&&l+r - 1>=c)
{
intersect = true;
// cout<<"AD\n";
}
/**
Mai avem de verificat BC si DC.
DC fiind paralel cu AB verificarea se face similar
doar ca coordonata liniei incepe de la l+r in loc de l
iar la BC se face ca la AD dar coordonata coloanei incepe cu c+r.
*/
int cl = l + r - 1; ///Coordonata liniei.
int cc = c + r - 1; ///Coordonata coloanei.
///DC
if(c<=cl&&c+r - 1>=cl)
{
intersect = true;
// cout<<"DC\n";
}
///BC
if(l<=cc&&l+r - 1>=cc)
{
intersect = true;
//cout<<"BC\n";
}
///Daca s-a intersectat macar odata incrementam contorul.
if(intersect == true)
cnt++;
}
cout< l+r-1 se intersecteaza cu diagonala. Similar facem si pentru restul.
Partea asta poti sa imi ceri sa ti-o explic si vei intelege foarte usor cu un desen.*/
/**
Putem avea maxim 2 intersectii. Sa spunem ca stim secundele la care
au loc respectivele intersectii(-1 daca nu au loc). Ce facem apoi?
Putem marca pe o scara a timpului secundele in care se intersecteaza.
Sa consideram un tablou Sec in care marcam cate rovere se intersecteaza in
acea secunda. Daca Sec[5] = 3 inseamna ca in secunda 5, 3 rovere se intersecteaza
cu diagonala principala.
Sa luam raza = 6 si o intersectie in secunda 9.(x = 9).
Perioada este 4 * raza - 4 = 20.
Prima intersectie va avea loc in secunda 20*0 + 9.
A doua intersectie va avea loc in secunda 20*1 + 9.
A treia intersectie va avea loc in secunda 20*2 + 9.
Si asa mai departe. Putem marca aceste secunde in stil ciur :
for(int i = x ; i<=S; i+=perioada)
Sec[i]++;
ANALIZA TIMPULUI IN CEL MAI RAU CAZ :
Cea mai mica perioada este 8 (pentru r = 3) asadar o astfel de marcare
in cel mai rau caz posibil , unde S = 100k va efectua 100k/8 operatii
pentru un singur rover cu o singura intersectie (12.5k). Pentru doua intersectii
vor fi 25k operatii. In restrictii ni se spune ca sunt maxim 1000 rovere care se intersecteaza
cu diagonala. Asadar in cel mai rau caz putem avea 25k * 1000 (25 mil operatii in care adunam in Sec[i]).
Am putea sa verificam de fiecare data cand adaugam frecventa daca este cea pe care o cautam dar atunci am
face 25 mil comparatii asa ca e mai bine sa parcurgem inca odata Sec la final decat sa verificam de fiecare
data daca secunda este raspunsul pe care il cautam.
Solutia oficiala propune sa folosim 3 vectori , in care sa pastram pozitia intersectiei 1 , poz intersectiei 2
si perioada fiecarui rover. Nu este necesar. Daca au loc intersectii marcam , daca nu , nu.
*/
for(int i = 1;i<=n;i++)
{
//cout<<"Rover "<>l>>c>>r;
///Secundele de la fiecare punct.
int secA = 1 , secB = r , secC = 2*r-1 , secD = 3*r-2;
int perioada = 4 * r - 4, cl = l+r-1, cc = c+r-1;
int punct1 = -1 , punct2 = -1;
///Avem intersectie in AB
if(c<=l&&c+r - 1>=l)
punct1 = secA + (l - c);
///Avem intersectie pe BC
if(l+1<=cc&&l+r-1>=cc)
{
if(punct1==-1)
punct1 = secB + (cc - l);
else punct2 = secB + (cc - l);
}
///Avem intersectie pe CD
if(cc>=cl&&cc-r+1<=cl)
{
if(punct1 == -1)
punct1 = secC + (cc - cl);
else punct2 = secC + (cc-cl);
}
///Avem intersectie pe DA
if(cl-1>=c&&cl-r+2<=c)
{
if(punct1 == -1)
punct1 = secD + (cl - c);
else punct2 = secD + (cl - c);
}
/**if(punct1!=-1)
cout<<"Punct 1: "<maxi)
maxi = Sec[i], secmin = i;
}
cout<