3698 - Bemo: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: Se dă o matrice cu R linii şi C coloane de numere distincte de la 1 la R * C. Bemo, personajul emoţional, doreşte să urmărească cel mai bun drum din colţul superior stânga, de coordonate (1, 1), în colţul inferior dreapta, de coordonate (R, C). Un drum este o secvenţă de numere din matrice în care fiecare număr se găseşte în jos sau la dreapta numărului anterior, adică dacă (i, j) este poziţia unui număr de pe un drum, atunci următorul număr poate fi...
 
No edit summary
 
Line 1: Line 1:
Se dă o matrice cu R linii şi C coloane de numere distincte de la 1 la R * C. Bemo, personajul emoţional, doreşte să urmărească cel mai bun drum din colţul superior stânga, de coordonate (1, 1), în colţul inferior dreapta, de coordonate (R, C). Un drum este o secvenţă de numere din matrice în care fiecare număr se găseşte în jos sau la dreapta numărului anterior, adică dacă (i, j) este poziţia unui număr de pe un drum, atunci următorul număr poate fi cel de pe poziţia (i + 1, j) sau cel de pe poziţia (i, j + 1). Pentru a determina dacă un drum A este mai bun decât un drum B, numerele fiecărui drum se vor sorta şi se va alege cel mai mic lexicografic, de exemplu [1,3,5,6,8] < [1,4,5,6,7].
 
== Date de intrare ==
Se dă o matrice cu <code>R</code> linii şi <code>C</code> coloane de numere distincte de la <code>1</code> la <code>R * C</code>. Bemo, personajul emoţional, doreşte să urmărească cel mai bun drum din colţul superior stânga, de coordonate <code>(1, 1)</code>, în colţul inferior dreapta, de coordonate <code>(R, C)</code>. Un drum este o secvenţă de numere din matrice în care fiecare număr se găseşte în jos sau la dreapta numărului anterior, adică dacă <code>(i, j)</code> este poziţia unui număr de pe un drum, atunci următorul număr poate fi cel de pe poziţia <code>(i + 1, j)</code> sau cel de pe poziţia <code>(i, j + 1)</code>. Pentru a determina dacă un drum <code>A</code> este mai bun decât un drum <code>B</code>, numerele fiecărui drum se vor sorta şi se va alege cel mai mic lexicografic, de exemplu <code>[1,3,5,6,8] < [1,4,5,6,7]</code>.
Fișierul de intrare bemoin.txt conține pe prima linie două numere naturale R și C, unde R este numărul liniilor, iar C numărul coloanelor matricei lui Bemo. Pe următoarele R linii se vor găsi câte C numere separate printr-un spaţiu. Fiecare număr va fi unic şi va fi cuprins în intervalul [1, R*C].
 
== Date de ieșire ==  
= Date de intrare =
Fișierul de ieșire bemoout.txt va conține R+C-1 numere reprezentând cel mai bun drum pe care Bemo îl poate alege. Numerele vor fi scrise separate printr-un spațiu.
Fișierul de intrare <code>bemoIN.txt</code> conține pe prima linie două numere naturale <code>R</code> și <code>C</code>, unde <code>R</code> este numărul liniilor, iar <code>C</code> numărul coloanelor matricei lui Bemo. Pe următoarele <code>R</code> linii se vor găsi câte <code>C</code> numere separate printr-un spaţiu. Fiecare număr va fi unic şi va fi cuprins în intervalul <code>[1, R*C]</code>.
== Restricții și precizări ==
 
*'''0 < R, C < 1501''';
= Date de ieșire =
*Pentru 40% din teste: 0 < R, C < 751;
Fișierul de ieșire <code>bemoOUT.txt</code> va conține <code>R+C-1</code> numere reprezentând cel mai bun drum pe care Bemo îl poate alege. Numerele vor fi scrise separate printr-un spațiu. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".
*Pentru 70% din teste: 0 < R, C < 1301;
 
*Spunem că un drum A = (a1, a2, …, aR+C-1) este mai mic lexicografic decât un drum B = (b1, b2,…, bR+C-1) dacă există o poziție p astfel încât ap < bp și a1 = b1, a2 = b2, …, ap-1 = bp-1.
= Restricții și precizări =
== Exemplul 1 ==
 
; bemoin.txt
* <code>0 < R, C < 1501</code>;
: 4 4
* Pentru 40% din teste: <code>0 < R</code>, <code>C < 751</code>;
: 7 4 13 3
* Pentru 70% din teste: <code>0 < R, C < 1301</code>;
: 8 11 12 2
* Spunem că un drum <code>A =</code> (<code>a1</code>, <code>a2</code>, …, <code>aR+C-1</code>) este mai mic lexicografic decât un drum <code>B =</code> (<code>b1</code>, <code>b2</code>,…, <code>bR+C-1</code>) dacă există o poziție <code>p</code> astfel încât <code>ap</code> <code>< bp</code> și <code>a1</code> <code>= b1</code>, <code>a2</code> <code>= b2</code>, …, <code>ap-1</code> <code>= bp-1</code>.
: 10 9 1 5
 
: 16 14 15 6
= Exemplu 1: =
; bemoout.txt
<code>bemoIN.txt</code>
: 7 4 11 9 1 5 6
4 4
<br>
7 4 13 3
== Exemplul 2 ==
8 11 12 2
; bemoin.txt
10 9 1 5
: 3 3
16 14 15 6
: 5 1 4
<code>bemoOUT.txt</code>
: 8 7 6
7 4 11 9 1 5 6
: 9 2 3
 
; bemoout.txt
= Exemplu 2: =
: 5 1 4 7 6 3
<code>bemoIN.txt</code>
<br>
4 1502
7 4 13 3
8 11 12 2
10 9 1 5
16 14 15 6
<code>bemoOUT.txt</code>
Datele nu corespund restrictiilor impuse
 
 
== Rezolvare ==  
== Rezolvare ==  
<syntaxhighlight lang="python" line>
<syntaxhighlight lang="python" line="1">
#3698 - Bemo
import sys
def find_best_path(R, C, matrix):
 
    if not (0 < R < 1501 and 0 < C < 1501):
NMAX = 2011
        return "Fals"
 
A = [[0] * NMAX for _ in range(NMAX)]
row = [0] * (NMAX * NMAX)
col = [0] * (NMAX * NMAX)
selected = [0] * (NMAX * NMAX)
elems = [0] * (2 * NMAX)


    path = []
R = C = nelems = 0


     i, j = 0, 0
def ReadInput():
     global R, C
    with open("bemoIN.txt", "r") as f:
        data = f.read().split()
    R, C = int(data[0]), int(data[1])
   
    # Verifică imediat după citirea dimensiunilor
    if not (0 < R < 1501 and 0 < C < 1501):
        with open("bemoOUT.txt", "w") as f:
            f.write("Datele nu corespund restrictiilor impuse\n")
        sys.exit()
   
    index = 2
    for i in range(1, R + 1):
        for j in range(1, C + 1):
            A[i][j] = int(data[index])
            row[A[i][j]] = i
            col[A[i][j]] = j
            index += 1


     while i < R and j < C:
def Solve():
         path.append(matrix[i][j])
    global nelems
    selected[A[1][1]] = 1
    nelems = 1
    elems[1] = A[1][1]
   
     if R == 1 and C == 1:
         return
   
    selected[A[R][C]] = 1
    nelems += 1
    elems[nelems] = A[R][C]


         if i < R - 1 and (j == C - 1 or matrix[i + 1][j] < matrix[i][j + 1]):
    for i in range(1, R * C + 1):
             i += 1
         if selected[i]:
        else:
            continue
             j += 1
       
        li, ls, before = 1, nelems, 0
       
        while li <= ls:
            mid = (li + ls) // 2
            if row[elems[mid]] <= row[i] and col[elems[mid]] <= col[i]:
                before = mid
                li = mid + 1
            else:
                ls = mid - 1
       
        if before == 0:
            continue
       
        if row[i] <= row[elems[before + 1]] and col[i] <= col[elems[before + 1]]:
            for j in range(nelems, before, -1):
                elems[j + 1] = elems[j]
             elems[before + 1] = i
            nelems += 1
             selected[i] = 1


     return path
     if nelems != R + C - 1:
        with open("bemoOUT.txt", "w") as f:
            f.write("Not enough elements selected!\n")
        sys.exit()


# Citim datele de intrare din fișierul "bemoin.txt"
def WriteOutput():
with open("bemoin.txt", "r") as file:
    with open("bemoOUT.txt", "w") as f:
    R, C = map(int, file.readline().split())
        for i in range(1, nelems + 1):
    matrix = [list(map(int, file.readline().split())) for _ in range(R)]
            f.write(f"{elems[i]}")
            if i < nelems:
                f.write(" ")
        f.write("\n")


# Găsim cel mai bun drum
def main():
result = find_best_path(R, C, matrix)
    ReadInput()
    Solve()
    WriteOutput()


# Scriem rezultatul în fișierul "bemoout.txt" sau afișăm "Fals" în cazul în care restricțiile nu sunt respectate
if __name__ == "__main__":
with open("bemoout.txt", "w") as file:
     main()
    if isinstance(result, list):
        file.write(" ".join(map(str, result)))
     else:
        file.write(result)


</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 10:19, 18 May 2024

Se dă o matrice cu R linii şi C coloane de numere distincte de la 1 la R * C. Bemo, personajul emoţional, doreşte să urmărească cel mai bun drum din colţul superior stânga, de coordonate (1, 1), în colţul inferior dreapta, de coordonate (R, C). Un drum este o secvenţă de numere din matrice în care fiecare număr se găseşte în jos sau la dreapta numărului anterior, adică dacă (i, j) este poziţia unui număr de pe un drum, atunci următorul număr poate fi cel de pe poziţia (i + 1, j) sau cel de pe poziţia (i, j + 1). Pentru a determina dacă un drum A este mai bun decât un drum B, numerele fiecărui drum se vor sorta şi se va alege cel mai mic lexicografic, de exemplu [1,3,5,6,8] < [1,4,5,6,7].

Date de intrare[edit | edit source]

Fișierul de intrare bemoIN.txt conține pe prima linie două numere naturale R și C, unde R este numărul liniilor, iar C numărul coloanelor matricei lui Bemo. Pe următoarele R linii se vor găsi câte C numere separate printr-un spaţiu. Fiecare număr va fi unic şi va fi cuprins în intervalul [1, R*C].

Date de ieșire[edit | edit source]

Fișierul de ieșire bemoOUT.txt va conține R+C-1 numere reprezentând cel mai bun drum pe care Bemo îl poate alege. Numerele vor fi scrise separate printr-un spațiu. Î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]

  • 0 < R, C < 1501;
  • Pentru 40% din teste: 0 < R, C < 751;
  • Pentru 70% din teste: 0 < R, C < 1301;
  • Spunem că un drum A = (a1, a2, …, aR+C-1) este mai mic lexicografic decât un drum B = (b1, b2,…, bR+C-1) dacă există o poziție p astfel încât ap < bp și a1 = b1, a2 = b2, …, ap-1 = bp-1.

Exemplu 1:[edit | edit source]

bemoIN.txt

4 4
7 4 13 3
8 11 12 2
10 9 1 5
16 14 15 6

bemoOUT.txt

7 4 11 9 1 5 6

Exemplu 2:[edit | edit source]

bemoIN.txt

4 1502
7 4 13 3
8 11 12 2
10 9 1 5
16 14 15 6

bemoOUT.txt

Datele nu corespund restrictiilor impuse


Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line="1"> import sys

NMAX = 2011

A = [[0] * NMAX for _ in range(NMAX)] row = [0] * (NMAX * NMAX) col = [0] * (NMAX * NMAX) selected = [0] * (NMAX * NMAX) elems = [0] * (2 * NMAX)

R = C = nelems = 0

def ReadInput():

   global R, C
   with open("bemoIN.txt", "r") as f:
       data = f.read().split()
   R, C = int(data[0]), int(data[1])
   
   # Verifică imediat după citirea dimensiunilor
   if not (0 < R < 1501 and 0 < C < 1501):
       with open("bemoOUT.txt", "w") as f:
           f.write("Datele nu corespund restrictiilor impuse\n")
       sys.exit()
   
   index = 2
   for i in range(1, R + 1):
       for j in range(1, C + 1):
           A[i][j] = int(data[index])
           row[A[i][j]] = i
           col[A[i][j]] = j
           index += 1

def Solve():

   global nelems
   selected[A[1][1]] = 1
   nelems = 1
   elems[1] = A[1][1]
   
   if R == 1 and C == 1:
       return
   
   selected[A[R][C]] = 1
   nelems += 1
   elems[nelems] = A[R][C]
   for i in range(1, R * C + 1):
       if selected[i]:
           continue
       
       li, ls, before = 1, nelems, 0
       
       while li <= ls:
           mid = (li + ls) // 2
           if row[elems[mid]] <= row[i] and col[elems[mid]] <= col[i]:
               before = mid
               li = mid + 1
           else:
               ls = mid - 1
       
       if before == 0:
           continue
       
       if row[i] <= row[elems[before + 1]] and col[i] <= col[elems[before + 1]]:
           for j in range(nelems, before, -1):
               elems[j + 1] = elems[j]
           elems[before + 1] = i
           nelems += 1
           selected[i] = 1
   if nelems != R + C - 1:
       with open("bemoOUT.txt", "w") as f:
           f.write("Not enough elements selected!\n")
       sys.exit()

def WriteOutput():

   with open("bemoOUT.txt", "w") as f:
       for i in range(1, nelems + 1):
           f.write(f"{elems[i]}")
           if i < nelems:
               f.write(" ")
       f.write("\n")

def main():

   ReadInput()
   Solve()
   WriteOutput()

if __name__ == "__main__":

   main()

</syntaxhighlight>