알고리즘/백준

[백준 파이썬] 17140 이차원 배열과 연산

rocku 2023. 7. 29. 15:56
 

17140번: 이차원 배열과 연산

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

www.acmicpc.net

Counter로 숫자의 빈도를 구하고 정렬해 배열의 행을 바꿔준다. C 연산은 배열을 전치시키고 R 연산을 하는 것과 같으므로 R 연산 하나만 구현하면 된다.

from collections import Counter

def calc(A):
    for i in range(len(A)):
        counts = Counter(A[i]) # 숫자의 개수를 센다
        del counts[0] # 0은 포함시키지 않으므로 제거
        counts = counts.items()
        # i번째 리스트 정렬 (숫자 빈도, 수 크기)
        A[i] = list(sum(sorted(counts, key=lambda x: [x[1], x[0]]), ()))
        if len(A[i]) > 100: # 길이가 100 넘는 경우는 앞에 100개만 사용
            A[i] = A[i][:101]

    max_len = max(list(map(len, A))) # 최대 길이를 기준으로
    for i in range(len(A)): # 짧은 행은 0 추가
        A[i] = A[i] + [0 for _ in range(max_len-len(A[i]))]
    
    return A


r, c, k = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(3)]

t = 0
while t <= 100: # 100초 이후에도 맞지 않다면 -1 출력
    if (r-1 >= len(A) or c-1 >= len(A[r-1]) # 배열의 크기보다 큰 범위를 찾거나
        or A[r-1][c-1] != k): # k가 아닐 경우에는 R 또는 C 연산 실행
        t += 1
        max_len = max(list(map(len, A))) 
        if len(A) >= max_len: # 행이 열보다 길거나 같을 경우
            A = calc(A) # R 연산 수행

        else: # 열이 행보다 길 경우
            A = list(map(list, zip(*A))) # 이차원 배열 전치
            A = calc(A) # R 연산 수행
            A = list(map(list, zip(*A))) # 이차원 배열 전치

    else: # k가 나왔다면 시간 출력
        print(t)
        break
else:
    print(-1)