Fie un vector v
sortat crescător cu N
elemente naturale nenule distincte pe care nu le cunoaştem, dar pe care ne propunem să le determinăm. Având la dispoziţie acest vector v
, cu ajutorul următorului algoritm de căutare binară (vezi Figura 1)
putem răspunde la queryuri de forma: Dându-se un număr X
şi un interval [a, b]
se cere să se determine cel mai mic element mai mare decât X
aflat în intervalul determinat de indicii a
şi b
, interval din vectorul v
. Se cunosc paşii pe care algoritmul de cautare binară i-a urmat pentru diferite valori ale tripletului (X, a, b)
.
Cerința
Dându-se N
(lungimea vectorului), Q
(numărul de query-uri apelate) şi cele Q
query-uri, să se determine vectorul iniţial. Dacă există mai multe soluţii se va afişa soluţia minim lexicografică. Dacă nu există soluţie se va afişa valoarea -1
. Un vector V1
se consideră mai mic lexicografic decât un alt vector V2
dacă există un indice i
astfel încât: V1[1] = V2[1]
, V1[2] = V2[2]
, …, V1[i-1] = V2[i-1]
și V1[i] < V2[i]
. Cele Q
query-uri sunt formate din:
X
– valoarea pe care o căutăm binar în vectorM
– numărul de iteraţii în algoritmul de căutare binară[a, b]
– intervalul în care se aplică algoritmul de cautare binară (perechea(a, b)
este considerată prima iteraţie în algoritm)M-1
perechi de indici reprezentând valorile afişate de algoritmul de căutare binară în urma fiecărei iteraţii
Date de intrare
Fișierul de intrare bsrec.in
conține pe prima linie o valoare T
reprezentând numărul de teste ce vor fi efectuate. Pentru fiecare din cele T
teste se va citi de pe prima linie valoarea N
(numărul de elemente ale vectorului), respectiv Q
(numărul de query-uri), despărţite prin câte un spaţiu. Următoarele linii descriu cele Q
query-uri. În cadrul unui query, prima linie va conține o pereche de numere (X, M)
despărţite printr-un spaţiu, unde X
reprezintă valoarea căutată în vector, iar M
numărul de paşi efectuaţi în căutarea binară a celei mai mici valori din vector care este mai mare decât X
. Pe următoarea linie a query-ului se găseşte perechea de valori (a, b)
având semnificaţia de mai sus. Următoarele M-1
linii conţin perechi (st, dr)
de valori naturale despărţite prin câte un spaţiu care reprezintă indicii stânga, respectiv dreapta ce sunt afişaţi în urma fiecărei iteraţii a algoritmului de mai sus.
Date de ieșire
Fișierul de ieșire bsrec.out
va conține T
linii, linia i
conţinând răspunsul pentru testul i
. Dacă testul admite soluţie, se vor afişa N
numere naturale nenule strict crescătoare ce vor reprezenta valorile vectorului v
. Deoarece există mai multe soluţii, se va afişa soluţia minim lexicografică. Dacă testul NU admite soluţie, se va afişa -1
.
Restricții și precizări
1 ≤ T ≤ 10
1 ≤ N, Q ≤ 1000
1 ≤ X ≤ 1 000 000 000
1 ≤ st ≤ dr ≤ N
, cu excepţia ultimei perechi din căutarea binară undest > dr
.- Pentru
20%
din punctajul total există teste cu1 ≤ N, Q ≤ 10
şi soluţia minim lexicografică admite valori până în20
. - Se garantează că
M ≤ 15
.
Exemplu
bsrec.in
2 5 3 3 4 1 5 1 2 2 2 2 1 30 3 2 4 4 4 5 4 25 2 4 5 4 3 5 3 30 4 1 5 1 2 2 2 2 1 3 3 2 4 4 4 5 4 5 2 4 5 4 3
bsrec.out
1 3 4 25 26 -1
Explicație
Fișierul conține două teste.
Primul test are trei query-uri:
- Primul query caută binar valoarea 3
în intervalul [1,5]
și face 4
iterații
- Cel de al doilea query caută binar valoarea 30
pe intervalul [2,4]
și face 3
iterații
- Cel de al treilea query caută binar valoarea 25
pe intervalul [4,5]
și face 2
iterații
Cel de al doilea test are 3
query-uri, dar NU admite soluție.
Cum e corect?
cout < "As la info";
cout << "As la info";
cout >> "As la info";
Felicitări! Poți mai mult?
Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.
Greșit, dar nu-i bai!
Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.
Rezolvare
Iată rezolvarea de 100 de puncte pentru problema bsrec:
#include<cstdio>
#include<algorithm>
using namespace std;
#define NMAX 1005
#define INF 1000000007
int tests, up[NMAX], down[NMAX], n, q;
int left[NMAX], right[NMAX], sol[NMAX];
void readAndRestrict() {
int value, steps;
scanf("%d%d", &value, &steps);
for(int i = 1; i <= steps; i++) {
scanf("%d%d", &left[i], &right[i]);
}
for(int i = 1; i < steps; i++) {
if(left[i] == left[i + 1])
down[right[i + 1] + 1] = max(down[right[i + 1] + 1], value);
else
up[left[i + 1] - 1] = min(up[left[i + 1] - 1], value - 1);
}
}
void setRestrictions() {
for(int i = 1; i <= n; i++) {
down[i] = 0;
up[i] = INF;
}
}
int main () {
freopen("bsrec.in","r",stdin);
freopen("bsrec.out","w",stdout);
scanf("%d",&tests);
for(; tests; tests--) {
scanf("%d%d",&n,&q);
setRestrictions();
for(int i = 1; i <= q; i++) {
readAndRestrict();
}
int have_sol = 1;
for(int i = 1; i <= n && have_sol; i++) {
sol[i] = max(sol[i - 1] + 1, down[i]);
if(sol[i] > up[i]) {
have_sol = 0;
}
}
if(!have_sol) {
printf("-1\n");
}
else {
for(int i = 1; i <= n; i++)
printf("%d ", sol[i]);
printf("\n");
}
}
return 0;
}
Atenție
Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa .
Rezolvarea problemei #2454 bsrec
Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #2454 bsrec de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.
Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!