1104 - Qvect
Enunt[edit | edit source]
Se consideră N vectori cu elemente întregi, numerotați de la 1 la N, sortați crescător, fiecare vector având un număr precizat de elemente.
Cerinţa[edit | edit source]
Să se răspundă la Q întrebări de tipul: a) 1 i j, cu semnificaţia: care este minimul dintre modulele diferențelor oricăror două elemente, primul element aparținând vectorului numerotat cu i, iar cel de al doilea element aparținând vectorului numerotat cu j ? b) 2 i j, cu semnificația: care este valoarea ce se găsește pe poziția mediană în vectorul obținut prin interclasarea vectorilor având numerele de ordine i,i+1,…,j (i<j).
Date de intrare[edit | edit source]
Fişierul de intrare qvect.in conţine pe prima linie două numerele naturale N Q, separate printr-un spațiu, ce reprezintă numărul de vectori, respectiv numărul de întrebări.
Pe fiecare dintre următoarele N linii se găsește descrierea unui vector sub forma: k a1 a2 … ak, unde k reprezintă numărul de elemente, iar a1 a2 … ak reprezintă elementele vectorului, separate prin câte un spațiu.
Pe fiecare dintre următoarele Q linii se găsește descrierea unei întrebări sub forma unui triplet de numere naturale: t i j, separate prin câte un spațiu, unde t reprezintă tipul întrebării şi poate lua numai valorile 1 sau 2, iar i și j au semnificația precizată în cerinţă.
Date de ieșire[edit | edit source]
Fişierul de ieşire qvect.out va conţine Q numere întregi, câte unul pe linie, reprezentând în ordine, răspunsurile la cele Q întrebări.
Restricţii şi precizări[edit | edit source]
- 1 ≤ N, i, j ≤ 100
- 1 ≤ Q ≤ 1000
- 1 ≤ t ≤ 2
- 1 ≤ k ≤ 5000
- -1 000 000 000 ≤ ap ≤ 1 000 000 000
- Prin valoarea aflată pe poziția mediană a unui vector a cu k elemente se înțelege valoarea elementului situat pe poziţia [k/2], adică partea întreagă a lui k / 2.
- 15% dintre teste vor conține numai întrebări de tipul 1
- 15% dintre teste vor conține numai întrebări de tipul 2
Exemplu[edit | edit source]
- qvect.in
3 3 7 1 4 5 8 11 18 19 6 2 4 5 10 21 29 4 13 14 15 15 2 2 3 1 2 3 2 1 3
- qvect.out
13 3 10
Explicație[edit | edit source]
Prima întrebare este de tipul 2. Vectorul nou obținut prin interclasarea vectorilor numerotați cu 2 și cu 3 este următorul: 2,4,5,10,13,14,15,15,21,29 și conține 6+4=10 elemente, valoarea elementului median este 13
A doua întrebare este de tipul 1. Diferența minimă se obține pentru perechea (10,13), unde valoarea 10 aparține vectorului numerotat cu 2, iar valoarea 13 aparține vectorului numerotat cu 3.
A treia întrebare este de tipul 2. Poziția mediană în vectorul nou obținut prin interclasare este (7+6+4)/2 = 8, deci valoarea ce se găsește pe poziția mediană este 10.
Rezolvare[edit | edit source]
<syntaxhighlight lang="python" line> def find_min_difference(vector1, vector2):
min_diff = float('inf') i, j = 0, 0 while i < len(vector1) and j < len(vector2): diff = abs(vector1[i] - vector2[j]) min_diff = min(min_diff, diff) if vector1[i] < vector2[j]: i += 1 else: j += 1 return min_diff
def merge_and_find_median(vector1, vector2):
merged_vector = [] i, j = 0, 0 while i < len(vector1) and j < len(vector2): if vector1[i] < vector2[j]: merged_vector.append(vector1[i]) i += 1 else: merged_vector.append(vector2[j]) j += 1 merged_vector.extend(vector1[i:]) merged_vector.extend(vector2[j:]) median_index = len(merged_vector) // 2 return merged_vector[median_index]
def main():
with open("qvect.in", "r") as fin: N, Q = map(int, fin.readline().split()) vectors = [list(map(int, fin.readline().split()))[1:] for _ in range(N)] queries = [tuple(map(int, fin.readline().split())) for _ in range(Q)]
with open("qvect.out", "w") as fout: for query in queries: t, i, j = query if t == 1: min_diff = find_min_difference(vectors[i-1], vectors[j-1]) fout.write(f"{min_diff}\n") elif t == 2: median = merge_and_find_median(vectors[i-1], vectors[j-1]) fout.write(f"{median}\n")
if __name__ == "__main__":
main()
</syntaxhighlight>