2970 - Paralele1

De la Universitas MediaWiki

Enunţ

Avem o matrice de dimensiuni N x M, cu elemente 0 și 1. Numim segment o secvență de cel puțin două valori 1 aflate una lângă alta, toate pe aceeași linie, sau toate pe aceeași coloană a matricei.

Cerința

Se cere determinarea numărului de perechi de segmente:

1. aflate pe linii distincte ale matricei;
2. aflate pe coloane distincte ale matricei;

Date de intrare

Fișierul paralele.in conține pe prima linie, separate prin câte un spațiu trei valori naturale, în ordine: T, N și M. Dacă T este 1 se rezolvă doar cerința 1, iar dacă T este 2 se rezolvă doar cerința 2. Începând cu linia a doua se află elementele matricei, o linie a matricei pe o linie a fișierului. Elementele de pe aceeași linie se separă prin câte un spațiu.

Date de ieșire

Fișierul paralele.out conține pe prima linie un număr natural reprezentând valoarea cerută.

Restricții și precizări

  • 1 ≤ T ≤ 2
  • Pentru 30 de puncte se garantează că T = 1, N = 2, 2 ≤ M ≤ 500 și toate elementele 1 de pe oricare dintre linii, dacă există, formează o secvență compactă.
  • Pentru alte 30 de puncte se garantează că T = 2, 2 ≤ N ≤ 500, 2 ≤ M ≤ 500 și pe oricare coloană sunt maximum două valori de 1 alăturate.
  • Pentru alte 9 puncte se garantează că T = 1, 2 ≤ N ≤ 500, 2 ≤ M ≤ 500.
  • Pentru alte 9 puncte se garantează că T = 2, 2 ≤ N ≤ 500, 2 ≤ M ≤ 500.
  • Pentru alte 12 puncte se garantează că T = 1, 35.000 ≤ N ≤ 40.000 și 8 ≤ M ≤ 10.
  • În concurs s-au acordat 10 puncte din oficiu. Aici se acordă pentru exemplul din enunț.

Exemplu 1

paralele.in
1 5 6
0 1 1 1 0 0
1 0 0 0 0 0
0 0 0 1 0 0
1 1 0 1 1 0
0 1 1 0 0 0
paralele.out
11

Explicație

Prima valoare din fișierul de intrare fiind 1, ne interesează segmente formate pe linii. Pe prima linie este o secvență de valori 1 formată din trei elemente. Ea produce trei segmente: cel cu primele două valori de 1, cel cu ultimele două valori de 1 și cel cu toate cele trei valori de 1. Pe linia a doua nu se găsește niciun segment, nefiind cel puțin două valori 1 alăturate. Pe linia a treia nu se găsește niciun segment, pe linia a patra sunt două segmente iar pe linia a cincea este un singur segment. Numărul cerut se obține astfel: fiecare dintre cele trei segmente de pe prima linie este paralel cu fiecare dintre segmentele de pe a patra și de pe a cincea linie iar segmentele de pe linia a patra sunt paralele cu segmentul de pe ultima linie. Pentru exemplul prezentat, dacă am fi avut T = 2 rezultatul calculat ar fi trebuit să fie 1 (segmentul de pe coloana a doua este paralel cu segmentul de pe coloana a patra).

Exemplu 2

paralele.in
0 3 3
1 2 3
4 5 6
7 8 9

Date de intrare invalide.

Rezolvare

#2970 paralele1
def count_parallel_segments_on_rows(matrix):
    count = 0
    for row in matrix:
        segment_started = False
        ones_count = 0
        for cell in row:
            if cell == 1:
                ones_count += 1
                if not segment_started:
                    segment_started = True
                    count += 1
            else:
                segment_started = False
                if ones_count > 1:
                    count += ones_count - 1
                ones_count = 0
    return count

def count_parallel_segments_on_columns(matrix):
    count = 0
    for col in range(len(matrix[0])):
        segment_started = False
        ones_count = 0
        for row in range(len(matrix)):
            if matrix[row][col] == 1:
                ones_count += 1
                if not segment_started:
                    segment_started = True
                    count += 1
            else:
                segment_started = False
                if ones_count > 1:
                    count += ones_count - 1
                ones_count = 0
    return count

def read_input(file_path):
    with open(file_path, 'r') as fin:
        T, N, M = map(int, fin.readline().split())
        matrix = [list(map(int, fin.readline().split())) for _ in range(N)]
        if not validate_input(T, N, M, matrix):
            print("Date de intrare invalide.")
            exit()
    return T, matrix

def write_output(file_path, count):
    with open(file_path, 'w') as fout:
        fout.write(str(count))

def validate_input(T, N, M, matrix):
    if T not in {1, 2}:
        return False
    if not (2 <= N <= 500):
        return False
    if not (2 <= M <= 500):
        return False
    if len(matrix) != N:
        return False
    for row in matrix:
        if len(row) != M:
            return False
        for cell in row:
            if cell not in {0, 1}:
                return False
    return True

def main():
    file_in = "paralele.in"
    file_out = "paralele.out"

    T, matrix = read_input(file_in)
    count = 0
    if T == 1:
        count = count_parallel_segments_on_rows(matrix)
    elif T == 2:
        count = count_parallel_segments_on_columns(matrix)
    write_output(file_out, count)

if __name__ == "__main__":
    main()