2959 - minecraft: Difference between revisions

From Bitnami MediaWiki
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Cerința ==
== Cerința ==
În lumea Minecraft, jucătorii își organizează inventarul folosind stive pentru a stoca diferite blocuri și obiecte. Ei pot adăuga blocuri la stivă sau pot scoate blocuri din stivă în funcție de nevoile lor de construcție. Sarcina ta este să implementezi un program care să simuleze aceste operațiuni asupra unei stive de blocuri.
Tommy a descoperit bine-cunoscutul joc Minecraft, joc care este axat pe creativitate și construcție, permițând jucătorilor să construiască, folosind o multitudine de cuburi texturate, o lume tridimensională. Harta lumii lui Tommy este o suprafață pătrată, pe care sunt desenate pătrate egale, alăturate, ce pot fi albastre sau verzi. Fiecare pătrat albastru corespunde unui cub albastru și fiecare pătrat verde corespunde unui cub verde. Sursele de apă sunt reprezentate de pătrate de culoare albastră. Fiecare pătrat verde are atașat un cost, reprezentat de lungimea celui mai scurt drum până la o sursă de apă. Două pătrate alăturate aparțin aceluiași drum dacă au o latură comună. Drumul ajunge la o sursă de apă, dacă, ultimul pătrat de pe drum are o latură comună cu pătratul corespunzător sursei de apă. Lungimea drumului este reprezentată de numărul de pătrate care formează drumul. Costul unei suprafețe este reprezentat de suma costurilor pătratelor care formează suprafața.
 
Pe harta din figura 3 sunt reprezentate costurile pătratelor verzi. Pentru a putea supraviețui în această lume, Tommy trebuie -și construiască o casă, având două posibilități:
 
a) Modul Supraviețuire: construiește o casă pe o zonă dreptunghiulară ce conține cel puțin o sursă de apă;<br>
b) Modul Creativ: construiește o casă pe o suprafață pătrată de arie maximă, ce nu conține surse de apă dar este învecinată cu cel puțin o sursă de apă. Dacă sunt mai multe astfel de suprafețe, alege una ce are cost minim.
 
== Date de intrare ==
== Date de intrare ==
Programul citește de la tastatură:
Cunoscând harta ce corespunde lumii lui Tommy, să se determine:


Un număr întreg n reprezentând numărul de operațiuni.
*numărul zonelor dreptunghiulare pe care poate construi casa în modul Supraviețuire;
O listă de n operațiuni, fiecare operațiune fiind de forma "PUSH X" (unde X este un tip de bloc) sau "POP".
*aria suprafeței pe care-și construiește casa și costul acesteia în modul Creativ.
== Date de ieșire ==
== Date de ieșire ==
Pe ecran se va afișa stiva rezultată după efectuarea tuturor operațiunilor. Dacă o operațiune "POP" este efectuată pe o stivă goală, se va afișa mesajul "Eroare: stivă goală".
Fișierul standard de ieșire are o singură linie ce conține:
 
*dacă C = 1, un singur număr ce reprezintă numărul zonelor dreptunghiulare pe care poate construi casa în modul Supraviețuire;
*dacă C = 2, două numere naturale separate prin spațiu, ce reprezintă aria suprafeței pe care construiește casa și costul acesteia, în modul Creativ.
== Restricții și precizări ==
== Restricții și precizări ==
*1 &les; '''n''' &les; 100
*2 ≤ N ≤ 1000
* 'x' este întotdeauna un tip de bloc reprezentat printr-un șir de caractere.
*Harta conține cel puțin o sursă de apă și cel puțin o zonă verde.


== Exemplu 1 ==
== Exemplu 1 ==
;Intrare
;Intrare
5
1<br>
PUSH Dirt
3<br>
PUSH Stone
VVA<br>
POP
AVV<br>
PUSH Wood
VVV
PUSH Iron


;Iesire
;Iesire
['Dirt', 'Wood', 'Iron']
19
 


== Rezolvare ==
== Rezolvare ==
<syntaxhighlight lang="python" line>
<syntaxhighlight lang="python" line>
def citeste_date():
def numara_zona_supravietuire(harta, N):
     try:
     def dfs(i, j):
         n = int(input("Introduceți numărul de operațiuni (n): "))
         if i < 0 or i >= N or j < 0 or j >= N or harta[i][j] == 'A' or vizitat[i][j]:
        operatiuni = []
            return
        for _ in range(n):
        vizitat[i][j] = True
            operatiune = input().strip()
        dfs(i + 1, j)
             operatiuni.append(operatiune)
        dfs(i - 1, j)
        return n, operatiuni
        dfs(i, j + 1)
     except ValueError:
        dfs(i, j - 1)
        return None, None
 
    vizitat = [[False] * N for _ in range(N)]
    zone_supravietuire = 0
 
    for i in range(N):
        for j in range(N):
             if harta[i][j] == 'V' and not vizitat[i][j]:
                zone_supravietuire += 1
                dfs(i, j)
 
     return zone_supravietuire
 


def valideaza_date(n, operatiuni):
def zona_maxima_creativ(harta, N):
     if not (1 <= n <= 100):
     def max_histogram_area(histogram):
         return False
         stack = []
    for operatiune in operatiuni:
         max_area = 0
         if not (operatiune.startswith("PUSH ") or operatiune == "POP"):
         index = 0
            return False
         if operatiune.startswith("PUSH ") and len(operatiune.split()) != 2:
            return False
        if operatiune.startswith("PUSH ") and not operatiune.split()[1].isalpha():
            return False
    return True


def proceseaza_operatiuni(n, operatiuni):
        while index < len(histogram):
    stiva = []
            if not stack or histogram[stack[-1]] <= histogram[index]:
    for operatiune in operatiuni:
                stack.append(index)
        if operatiune.startswith("PUSH "):
                index += 1
            _, bloc = operatiune.split()
            stiva.append(bloc)
        elif operatiune == "POP":
            if stiva:
                stiva.pop()
             else:
             else:
                 print("Eroare: stivă goală")
                 top_of_stack = stack.pop()
     return stiva
                area = (histogram[top_of_stack] *
                        ((index - stack[-1] - 1) if stack else index))
                max_area = max(max_area, area)
 
        while stack:
            top_of_stack = stack.pop()
            area = (histogram[top_of_stack] *
                    ((index - stack[-1] - 1) if stack else index))
            max_area = max(max_area, area)
 
        return max_area
 
    max_area = 0
    dp = [0] * N
 
    for i in range(N):
        for j in range(N):
            if harta[i][j] == 'V':
                dp[j] += 1
            else:
                dp[j] = 0
        max_area = max(max_area, max_histogram_area(dp))
 
    return max_area
 
 
def numara_toate_zonele(harta, N):
    zone_supravietuire = 0
    for top in range(N):
        for left in range(N):
            for bottom in range(top, N):
                for right in range(left, N):
                    found_water = False
                    for i in range(top, bottom + 1):
                        for j in range(left, right + 1):
                            if harta[i][j] == 'A':
                                found_water = True
                    if found_water:
                        zone_supravietuire += 1
     return zone_supravietuire
 


def main():
def main():
     n, operatiuni = citeste_date()
     K = int(input().strip())
      
     N = int(input().strip())
     if n is None or operatiuni is None or not valideaza_date(n, operatiuni):
 
         print("Datele de intrare nu corespund restricțiilor impuse.")
    assert 2 <= N <= 1000, "N trebuie sa fie intre 2 si 1000"
         return
 
      
     harta = []
    print("Datele de intrare corespund restricțiilor impuse.")
    for _ in range(N):
     rezultat = proceseaza_operatiuni(n, operatiuni)
         row = list(input().strip())
     print(rezultat)
        assert len(row) == N, "Fiecare rând trebuie să aibă exact N caractere"
        assert all(c in {'A', 'V'} for c in row), "Harta poate contine doar caracterele 'A' si 'V'"
         harta.append(row)
 
     if K == 1:
        zone_supravietuire = numara_toate_zonele(harta, N)
        print(f"{zone_supravietuire}")
     elif K == 2:
        zona_creativ = zona_maxima_creativ(harta, N)
        print(f"{zona_creativ}")
     else:
        print("Valoare K invalidă")
 
 
if __name__ == "__main__":
    main()


if __name__ == "__main__":
if __name__ == "__main__":

Latest revision as of 22:48, 2 June 2024

Cerința[edit | edit source]

Tommy a descoperit bine-cunoscutul joc Minecraft, joc care este axat pe creativitate și construcție, permițând jucătorilor să construiască, folosind o multitudine de cuburi texturate, o lume tridimensională. Harta lumii lui Tommy este o suprafață pătrată, pe care sunt desenate pătrate egale, alăturate, ce pot fi albastre sau verzi. Fiecare pătrat albastru corespunde unui cub albastru și fiecare pătrat verde corespunde unui cub verde. Sursele de apă sunt reprezentate de pătrate de culoare albastră. Fiecare pătrat verde are atașat un cost, reprezentat de lungimea celui mai scurt drum până la o sursă de apă. Două pătrate alăturate aparțin aceluiași drum dacă au o latură comună. Drumul ajunge la o sursă de apă, dacă, ultimul pătrat de pe drum are o latură comună cu pătratul corespunzător sursei de apă. Lungimea drumului este reprezentată de numărul de pătrate care formează drumul. Costul unei suprafețe este reprezentat de suma costurilor pătratelor care formează suprafața.

Pe harta din figura 3 sunt reprezentate costurile pătratelor verzi. Pentru a putea supraviețui în această lume, Tommy trebuie să-și construiască o casă, având două posibilități:

a) Modul Supraviețuire: construiește o casă pe o zonă dreptunghiulară ce conține cel puțin o sursă de apă;
b) Modul Creativ: construiește o casă pe o suprafață pătrată de arie maximă, ce nu conține surse de apă dar este învecinată cu cel puțin o sursă de apă. Dacă sunt mai multe astfel de suprafețe, alege una ce are cost minim.

Date de intrare[edit | edit source]

Cunoscând harta ce corespunde lumii lui Tommy, să se determine:

  • numărul zonelor dreptunghiulare pe care poate construi casa în modul Supraviețuire;
  • aria suprafeței pe care-și construiește casa și costul acesteia în modul Creativ.

Date de ieșire[edit | edit source]

Fișierul standard de ieșire are o singură linie ce conține:

  • dacă C = 1, un singur număr ce reprezintă numărul zonelor dreptunghiulare pe care poate construi casa în modul Supraviețuire;
  • dacă C = 2, două numere naturale separate prin spațiu, ce reprezintă aria suprafeței pe care construiește casa și costul acesteia, în modul Creativ.

Restricții și precizări[edit | edit source]

  • 2 ≤ N ≤ 1000
  • Harta conține cel puțin o sursă de apă și cel puțin o zonă verde.

Exemplu 1[edit | edit source]

Intrare

1
3
VVA
AVV
VVV

Iesire

19

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line> def numara_zona_supravietuire(harta, N):

   def dfs(i, j):
       if i < 0 or i >= N or j < 0 or j >= N or harta[i][j] == 'A' or vizitat[i][j]:
           return
       vizitat[i][j] = True
       dfs(i + 1, j)
       dfs(i - 1, j)
       dfs(i, j + 1)
       dfs(i, j - 1)
   vizitat = [[False] * N for _ in range(N)]
   zone_supravietuire = 0
   for i in range(N):
       for j in range(N):
           if harta[i][j] == 'V' and not vizitat[i][j]:
               zone_supravietuire += 1
               dfs(i, j)
   return zone_supravietuire


def zona_maxima_creativ(harta, N):

   def max_histogram_area(histogram):
       stack = []
       max_area = 0
       index = 0
       while index < len(histogram):
           if not stack or histogram[stack[-1]] <= histogram[index]:
               stack.append(index)
               index += 1
           else:
               top_of_stack = stack.pop()
               area = (histogram[top_of_stack] *
                       ((index - stack[-1] - 1) if stack else index))
               max_area = max(max_area, area)
       while stack:
           top_of_stack = stack.pop()
           area = (histogram[top_of_stack] *
                   ((index - stack[-1] - 1) if stack else index))
           max_area = max(max_area, area)
       return max_area
   max_area = 0
   dp = [0] * N
   for i in range(N):
       for j in range(N):
           if harta[i][j] == 'V':
               dp[j] += 1
           else:
               dp[j] = 0
       max_area = max(max_area, max_histogram_area(dp))
   return max_area


def numara_toate_zonele(harta, N):

   zone_supravietuire = 0
   for top in range(N):
       for left in range(N):
           for bottom in range(top, N):
               for right in range(left, N):
                   found_water = False
                   for i in range(top, bottom + 1):
                       for j in range(left, right + 1):
                           if harta[i][j] == 'A':
                               found_water = True
                   if found_water:
                       zone_supravietuire += 1
   return zone_supravietuire


def main():

   K = int(input().strip())
   N = int(input().strip())
   assert 2 <= N <= 1000, "N trebuie sa fie intre 2 si 1000"
   harta = []
   for _ in range(N):
       row = list(input().strip())
       assert len(row) == N, "Fiecare rând trebuie să aibă exact N caractere"
       assert all(c in {'A', 'V'} for c in row), "Harta poate contine doar caracterele 'A' si 'V'"
       harta.append(row)
   if K == 1:
       zone_supravietuire = numara_toate_zonele(harta, N)
       print(f"{zone_supravietuire}")
   elif K == 2:
       zona_creativ = zona_maxima_creativ(harta, N)
       print(f"{zona_creativ}")
   else:
       print("Valoare K invalidă")


if __name__ == "__main__":

   main()

if __name__ == "__main__":

   main()

</syntaxhighlight>