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
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
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
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
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 :
sort2distIN.txt
4 5 7 6 2
sort2distOUT.txt
2 2 4 2 1
Explicație
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 :
sort2distIN.txt
1001 5 7 6 2
sort2distOUT.txt
Datele nu corespund restrictiilor impuse
Rezolvare
<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>