0565 - Acoperire

De la Universitas MediaWiki
Versiunea din 29 aprilie 2023 11:04, autor: AndorGiulia (discuție | contribuții) (Pagină nouă: Sursă: [https://www.pbinfo.ro/probleme/565/acoperire] == Cerință == Gigel deține un teren de formă dreptunghiulară, împărțite în '''n•m''' sectoare, dispuse pe '''n''' linii și '''m''' coloane. În anumite sectoare sunt instalate camere de luat vederi. Fiecare cameră acoperă anumite sectoare ale terenului, pe diagonală și are o anumită putere '''k''' reprezentând numărul de sectoare pe care le acoperă pe fiecare din cele '''4''' direcții, inclusiv sector...)
(dif) ← Versiunea anterioară | Versiunea curentă (dif) | Versiunea următoare → (dif)

Sursă: [1]

Cerință

Gigel deține un teren de formă dreptunghiulară, împărțite în n•m sectoare, dispuse pe n linii și m coloane. În anumite sectoare sunt instalate camere de luat vederi. Fiecare cameră acoperă anumite sectoare ale terenului, pe diagonală și are o anumită putere k reprezentând numărul de sectoare pe care le acoperă pe fiecare din cele 4 direcții, inclusiv sectorul în care se află camera. Determinați câte sectoare ale terenului nu sunt acoperite de nici o cameră.

Date de intrare

Programul citește de la tastatură numerele n m k, reprezentând dimensiunile terenului și numărul de camere, apoi k triplete i j p, reprezentând coordonatele fiecărei camere șî puterea ei.

Date de ieșire

Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt corecte.". Programul va afișa pe ecran numărul C, reprezentând numărul de sectoare neacoperite. În caz contrar, se va afișa pe ecran: "Datele nu sunt comform restricțiilor impuse.".

Restricții și precizări

  • 1 ≤ n , m ≤ 1000
  • 1 ≤ p ≤ 1000
  • 1 ≤ j ≤ m
  • 1 ≤ p ≤ min(n,m)
  • o cameră poate acoperi un sector în care se află o altă cameră

Exemple

Exemplu 1

Date de intrare
1 7 2
4 2 3
4 5 4
Date de ieșire
16

Rezolvare

def citeste_n_m_k():
    while True:
        try:
            n = int(input("Introduceti numarul n: "))
            m = int(input("Introduceti numarul m: "))
            k = int(input("Introduceti numarul k: "))
            if 1 <= n <= 1000 and 1 <= m <= 1000 and 1 <= k <= 1000:
                print("Datele sunt corecte.")
                return n,m,k
            else:
                print("Datele nu sunt conform restrictiilor impuse.")
        except ValueError:
            print("Trebuie introduse doar numere intregi.")


def citeste_triplet(n, m):
    valori = []
    for i in range(n):
        while True:
            try:
                i,j,p = map(int, input("Introduceti tripletul de valori separate prin spatiu: ").split())
                if 1 <= i <= n and 1 <= j <= m and 1 <= p <= min(n,m):
                    print("Datele sunt corecte.")
                    valori.append((i,j,p))
                    break
                else:
                    print("Datele nu sunt conform restrictiilor impuse.")
            except ValueError:
                print("Trebuie introduse doar valori numerice.")

    return valori


def Acoperire(valori, n, m):
    a = [[-1 for j in range(m+1)] for i in range(n+1)]
    cnt = 0
    for i,j,p in valori:
        a[i][j] = p
        for l in range(1, p+1):
            if i + l <= n and j + l <= m:
                a[i+l][j+l] = p
            if i + l <= n and j - l > 0:
                a[i+l][j-l] = p
            if i - l > 0 and j + l <= m:
                a[i-l][j+l] = p
            if i - l > 0 and j - l > 0:
                a[i-l][j-l] = p
    for i in range(1, n+1):
        for j in range(1, m+1):
            if a[i][j] == -1:
                cnt += 1
    return cnt


if _name_ == '_main_':
    n, m, k = citeste_n_m_k()
    valori = citeste_triplet(k, m)
    cnt = Acoperire(valori, n, m)
    print("Numarul de sectoare neacoperite este:", cnt)

Explicatie

Acest cod este o implementare a unui algoritm care calculează numărul de sectoare neacoperite de o matrice dată, folosind informații despre un set de triplete formate din trei valori întregi (i, j, p) care semnifică: linia i, coloana j și raza de acoperire p a unui sector circular centrare în (i,j).
Funcția citeste_n_m_k() citește de la tastatură valorile pentru n, m și k, reprezentând dimensiunile matricei și numărul de triplete, iar apoi verifică dacă valorile sunt conforme cu restricțiile impuse: n, m și k trebuie să fie între 1 și 1000. Dacă valorile sunt corecte, funcția le returnează.
Funcția citeste_triplet(n, m) primește numărul de triplete k și dimensiunea m și citește de la tastatură k triplete (i, j, p), reprezentând coordonatele centrului sectorului circular și raza de acoperire a acestuia. După citire, funcția verifică dacă tripletele sunt conforme cu restricțiile impuse: i și j trebuie să fie între 1 și n și respectiv între 1 și m, iar p trebuie să fie între 1 și min(n,m). Tripletele valide sunt adăugate la o listă de valori și apoi returnate.
Funcția Acoperire(valori, n, m) primește lista de valori citite anterior și dimensiunile matricei și calculează numărul de sectoare neacoperite. Înainte de a începe procesul de acoperire, se creează o matrice a de dimensiuni n+1 x m+1, inițializată cu valoarea -1 pentru toate elementele, pentru a putea verifica mai ușor dacă un sector a fost acoperit sau nu. Apoi, pentru fiecare triplet de valori citite, se actualizează matricea a, setând valoarea razei p pentru fiecare element de pe cercul centrat în (i,j). Se actualizează de asemenea și elementele din interiorul cercului, mărind raza de la 1 la p. La final, se numără câte elemente din matricea a au valoarea -1, semnificând sectoarele neacoperite, și se returnează acest număr.
Funcția main() apelează funcțiile citeste_n_m_k(), citeste_triplet(k, m) și Acoperire(valori, n, m) și afișează numărul de sectoare neacoperite.