2959 - minecraft: Difference between revisions
Benzar Ioan (talk | contribs) |
Benzar Ioan (talk | contribs) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== Cerința == | == Cerința == | ||
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ă;<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 == | ||
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 == | == Date de ieșire == | ||
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 == | ||
* | *2 ≤ N ≤ 1000 | ||
* | *Harta conține cel puțin o sursă de apă și cel puțin o zonă verde. | ||
== Exemplu 1 == | == Exemplu 1 == | ||
;Intrare | ;Intrare | ||
1<br> | |||
3<br> | |||
VVA<br> | |||
AVV<br> | |||
VVV | |||
;Iesire | ;Iesire | ||
19 | |||
== Rezolvare == | == Rezolvare == | ||
<syntaxhighlight lang="python" line> | <syntaxhighlight lang="python" line> | ||
def | 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 | |||
for | 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 | |||
return | |||
max_area = 0 | |||
dp = [0] * N | |||
for | |||
for i in range(N): | |||
for j in range(N): | |||
if harta[i][j] == 'V': | |||
dp[j] += 1 | |||
else: | else: | ||
dp[j] = 0 | |||
return | 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(): | ||
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()) | |||
print( | 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>