4051 - Lumina

De la Universitas MediaWiki
Versiunea pentru tipărire nu mai este suportată și poate avea erori de randare. Vă rugăm să vă actualizați bookmarkurile browserului și să folosiți funcția implicită de tipărire a browserului.

Cerința

Se consideră un panou de dimensiuni n×m

pe care sunt așezate nm becuri. Becul de pe rândul i și coloana j se notează (i,j). Inițial, fiecare bec este stins (0) sau aprins (1). Putem efectua următoarele comenzi de oricâte ori:

  • Se alege un rând i(1≤i≤n) și se inversează starea tuturor becurilor de pe rândul i (0→1,1→0);
  • Se alege o coloană j (1≤j≤m) și se inversează starea tuturor becurilor de pe coloana j (0→1,1→0).

Găsiți o secvență cu un număr minim de comenzi care conduce la aprinderea tuturor becurilor.

Date de intrare

Pe prima linie se află numerele n și m. Pe a i-a dintre următoarele n linii se găsește o secvență de mnumere care sunt fie 0, fie 1. Al j-lea număr reprezintă starea becului (i,j).

Date de ieșire

Programul va afișa DA, dacă este posibilă aprinderea tuturor becurilor și NU în caz contrar. Dacă răspunsul este DA, pe a doua linie se vor afișa indicii liniilor inversate. Apoi, pe a treia linie se vor afișa indicii coloanelor inversate. Atât pe a doua, cât și pe a treia linie, numerele vor fi afișate în ordine crescătoare.

Restricții si precizări

  • 2≤n,m≤500
  • Se garantează că pentru testele date, există o unică soluție optimă
  • Pentru 10 de puncte, se garantează că soluția optimă inversează doar rânduri
  • Pentru alte 10 de puncte, se garantează că soluția optimă inversează un rând și o coloană

Exemplu1

Intrare

2 5

1 0 1 1 0

0 1 0 0 1

Iesire

DA

2

2 5

Explicație

Se inversează rândul 2 și coloanele 2 și 5.

Exemplu 2:

Intrare

2 5

1 0 1 1 1

0 1 0 0 1

Ieșire

NU

Explicație

Se poate demonstra că nu există soluție pentru acest test.

Rezolvare

def validare_date(n, m):
    if not (2 <= n <= 500) or not (2 <= m <= 500):
        raise ValueError("Dimensiunile matricei trebuie să fie între 2 și 500 inclusiv.")

def schimba_randuri_coloane(matrice, randuri, coloane):
    randuri_schimbate = []
    coloane_schimbate = []

    # Parcurgem toate liniile și coloanele și verificăm dacă becul trebuie inversat
    for i in range(randuri):
        if matrice[i][0] == 0:
            randuri_schimbate.append(i + 1)  # Adăugăm indexul rândului pentru a fi inversat
            for j in range(coloane):
                matrice[i][j] = 1 if matrice[i][j] == 0 else 0  # Inversăm starea becului

    for j in range(coloane):
        count = sum(matrice[i][j] for i in range(randuri))
        if count <= randuri // 2:
            coloane_schimbate.append(j + 1)  # Adăugăm indexul coloanei pentru a fi inversată
            for i in range(randuri):
                matrice[i][j] = 1 if matrice[i][j] == 0 else 0  # Inversăm starea becului

    return matrice, randuri_schimbate, coloane_schimbate

def all_lights_on(matrice, randuri, coloane):
    for randuri in matrice:
        if 0 in randuri:
            return False
    return True

def rezolva_luminile():
    n, m = map(int, input().split())
    matrice = [list(map(int, input().split())) for _ in range(n)]
    matrice, randuri_schimbate, coloane_schimbate = schimba_randuri_coloane(matrice, n, m)

    if all_lights_on(matrice, n, m):
        print("DA")
        print(" ".join(map(str, randuri_schimbate)))
        print(" ".join(map(str, coloane_schimbate)))
    else:
        print("NU")

if __name__=="__main__":
    rezolva_luminile()