Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
/**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<
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)