1225 - Sort 2 Dist
Jocul pe care îl joaca Robo atunci când se plictisește este un joc inteligent pentru roboței. Pe ecranul tabletei lui roboțești, sunt N
căsuțe de formă pătrată, cu latura egală cu 1
. Căsuțele sunt așezate pe un rând, una lângă alta, fiind etichetate, în această ordine, cu numere de la 1
la N
. Fiecare căsuță conține câte un număr natural, identificatorul câte unuia dintre prietenii săi, roboței, ca și el. Identificatorii se pot repeta.
Robo poate interschimba conținutul a două căsuțe, numai dacă distanța dintre centrele acestora pe orizontală este egală cu distanța dintre brațele sale; distanța, pe orizontală, dintre centrele a două căsuțe etichetate cu i
, respectiv cu j
, este j-i
(1≤i<j≤N
).
El își poate fixa în orice moment distanța dintre brațe la 1
sau își poate dubla distanța curentă dintre brațe, de oricâte ori este necesar, fără a depăși valoarea N-1
. Astfel, distanța dintre brațele sale poate fi 1
, apoi, prin dublare, 2
, apoi, prin dublare 4
, apoi, prin dublare 8
etc. La începutul jocului, distanța dintre brațele lui Robo este 1
. De fiecare dată când consideră convenabilă distanța dintre brațe, realizează o interschimbare.
Cerința[edit | edit source]
Se cere ca Robo să așeze identificatorii în căsuțe în ordine crescătoare, prin maximum 12500
interschimbări de tipul celei precizate mai sus.
Date de intrare[edit | edit source]
Fișierul de intrare sort2distIN.txt
conține:
- pe prima linie numărul natural
N
, cu semnificația din enunț; - pe următoarele
N
linii,N
numere, reprezentând, în această ordine, identificatorii aflați în căsuțele tabletei (identificatorul de pe liniai
se află în căsuțai-1
).
Date de ieșire[edit | edit source]
Fișierul de ieșire sort2distOUT.txt
va conține:
- pe prima linie un număr natural
M
, reprezentând numărul de interschimbări realizate de Robo (nu neapărat numărul minim de interschimbări necesare); - pe fiecare dintre următoarele
M
linii (doar dacăM
este nenul), câte două numere naturale, separate prin câte un spațiu, reprezentând etichetele căsuțelor al căror conținut s-a interschimbat, în ordinea realizării acestor interschimbări. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".
Restricții și precizări[edit | edit source]
1 ≤ N ≤ 1000
;- identificatorii sunt numere naturale de maximum
30
de cifre; - pentru 25% din punctaj, fișierele de test conțin numere cu maximum
18
cifre; - pentru 25% din punctaj,
N ≤ 100
.
Exemplul 1 :[edit | edit source]
sort2distIN.txt
4 5 7 6 2
sort2distOUT.txt
2 2 4 2 1
Explicație[edit | edit source]
Tableta are 4
căsuțe, conținând, în această ordine, identificatorii (5,7,6,2)
.
Pentru ordonarea crescătoare s-au realizat 2
interschimbări:
- s-a interschimbat conținutul căsuțelor
2
și4
(distanța dintre centrele lor fiind2
), identificatorii din căsuțe fiind acum(5, 2, 6, 7)
; - s-a interschimbat conținutul căsuțelor
1
și2
(distanța dintre centrele lor fiind1
), identificatorii din căsuțe fiind acum(2, 5, 6, 7)
, ordonați crescător.
Exemplul 2 :[edit | edit source]
sort2distIN.txt
1001 5 7 6 2
sort2distOUT.txt
Datele nu corespund restrictiilor impuse
Rezolvare[edit | edit source]
<syntaxhighlight lang="python" line="1"> import os
DIM = 1010
sol = [] v = [0] * DIM s = [""] * DIM aux = "" w = [""] * DIM
def myStrcmp(s1, s2):
if len(s1) == len(s2): return (s1 > s2) - (s1 < s2) else: return -1 if len(s1) < len(s2) else 1
def schimba(x, y):
sol.append((x, y)) aux = v[x] v[x] = v[y] v[y] = aux
def verify_restrictions(n, strings):
if not (1 <= n <= 1000): return False for string in strings: if not (1 <= len(string) <= 30): return False return True
def main():
with open("sort2distIN.txt", "r") as fin: n = int(fin.readline().strip()) for i in range(1, n + 1): s[i] = fin.readline().strip() w[i] = s[i]
if not verify_restrictions(n, s[1:n+1]): with open("sort2distOUT.txt", "w") as fout: fout.write("Datele nu corespund restrictiilor impuse") return
for i in range(1, n): for j in range(i + 1, n + 1): if myStrcmp(w[i], w[j]) > 0: w[i], w[j] = w[j], w[i]
k = 1 for i in range(2, n + 1): if myStrcmp(w[i], w[k]) != 0: k += 1 w[k] = w[i]
for i in range(1, n + 1): st = 1 dr = k while st <= dr: mid = (st + dr) // 2 if myStrcmp(s[i], w[mid]) == 0: v[i] = mid break if myStrcmp(s[i], w[mid]) < 0: dr = mid - 1 else: st = mid + 1
for i in range(n, 1, -1): m = v[1] p = 1 for j in range(2, i + 1): if v[j] > m: m = v[j] p = j if p != i: d = i - p
putere = 1 last = p while d != 0: if d % 2 == 1: schimba(last + putere, last) last += putere d = d // 2 putere *= 2
with open("sort2distOUT.txt", "w") as fout: fout.write(f"{len(sol)}\n") for x, y in sol: fout.write(f"{x} {y}\n")
if __name__ == "__main__":
main()
</syntaxhighlight>