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
/** Problema propusa va folosi urmatoarele : - Cautare binara pe rezultat - Fereastra glisanta / sliding window technique Enunt pe scurt : Se sorteaza crescator toate sumele subsecventelor dintr-un sir de valori si le punem intr-un tablou v. Se cere afisarea elementului v[k]. Ex : sir : 1,2,4 , k = 5 Subsecventele si sumele lor sunt : (1)-> 1 (1,2)-> 3 (1,2,4)-> 7 (2)-> 2 (2,4)-> 6 (4) -> 4 Sumele sortate sunt : 1 , 2 , 3, 4 , 6 , 7. V[k] = 6. (k=5)(Raspunsul). Sa spunem ca avem n elemente. Vom avea n*(n+1)/2 subsecvente (in exemplu n = 3 -> 3*4/2 = 6 subsevente) Din restrictii n <= 10.000 asadar putem avea pana la 50 de milioane de subsecvente... Evident nu putem simula ce ne cere problema (eu nu propun probleme foarte usoare in caz de a-ti observat) REZOLVARE F(x) - returneaza cate subsecvente sunt mai mici sau egale cu x; Daca stim aceasta informatie stim a cata subsecventa este ultima subsecventa cu suma x. Deci daca gasim cel mai mic x pentru care F(x) >= k atunci si elementul k din sirul sortat va avea aceiasi suma; Sa luam un sir sortat de sume ale subsecventelor sa intelegem mai bine : Sir 1 2 4 6 6 6 8 10 (suma = 43) Poz 1 2 3 4 5 6 7 8 (Vrem sa returnam Sir[5] = 6 (acel 6 de la mijloc.) Cand f(x) >= k vom salva acea pozitie evident. k = 5 , cand F(x) < k -> st = mid+1, cand F(x) >= k -> dr = mid-1 si salvam mid ca noua solutie. st = 1 , dr = 43 -> mid = 21 -> F(x) = 8 (evident toate sumele sunt mai mici decat 21) (noua solutie = mid) st = 1, dr = 20 -> mid = 10 -> F(x) = 8 (iarasi) (noua solutie = mid) st = 1, dr = 9 -> mid = 5 -> F(x) = 3 (de la pozitia 4 incolo sunt mai mari sumele decat 5) st = 6, dr = 9 -> mid = 7 -> F(x) = 6 (noua solutie = mid) st = 6, dr = 6 -> mid = 6 -> F(x) = 6 (noua solutie = mid) st = 6, dr = 5 -> exit. sol = 6 De aceea luam f(x)>=k si nu doar f(x)==k, pentru ca putem avea mai multe subsecvente cu aceiasi suma. Acum sper ca reiese cum ne ajuta functia F(x) si cum putem folosi rezultatele ei in cautarea binara pentru a determina valoarea sumei de pe pozitia k. Dar pana acum am folosit doar rezultatele functiei din ochi pentru ca putem vedea din datele exemplului.. Acum complexitatea solutiei va fi logN ( de la cautarea binara) * ceva (complexitatea functiei F(x)) Dar stim deja ca n^2 nu este suficient de eficient deci e clar ca complexitatea necesara functiei F(x) este O(n)... Deci cam printr-o singura trecere a elementelor va trebui sa spunem cate subsecvente au suma mai mica sau egala decat x. Nu avem asa de multe optiuni de considerat. E clar ca vom avea nevoie de fereastra glisanta / sliding window technique. Vom retine suma elementelor de la i la j. Cand mutam i suma scade , cand mutam j suma creste. Asadar daca suma de la i la j <= x atunci toate subsecventele cu j fixat acolo si cu i crescand pana la j vor avea si ele suma mai mica sau egala decat x (suma scade) deci putem din start sa crestem sol cu lungimea intervalului (j - i + 1). Daca suma de la i la j este mai mare decat x atunci mutam i pana cand suma este mai mica sau egala. Aveti aici functia F(x) in cod. */ int F(int x) { int sol = 0; // cate subsecvente au suma mai mica sau egala decat x int i = 1, j = 1, // cei doi pointeri int sum = 0; // suma de la i la j while(i<=n&&j<=n) { sum+=v[j]; while(sum>x) //ne asiguram ca suma e mai mica sau egala decat x. sum-=v[i], i++; //mutam capatul din stanga al intervalului. sol+=(j - i + 1); //crestem sol cu lungimea intervalului. j++; } return sol; }
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)