알고리즘/Python

[python] 백준 17140 - 이차원 배열과 연산

제주도랏맨 2023. 4. 6. 08:45

출처 : 백준, https://www.acmicpc.net/problem/17140

 

17140번: 이차원 배열과 연산

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

www.acmicpc.net

# 배열의 크기는 3 x 3
# 정렬은 1초마다 빈도 -> 숫자 순으로 오름차순 정렬하되 [숫자, 빈도, 숫자, 빈도, ...] 꼴로 새로운 배열은 만듬
    # 정렬 시 0은 세지 않음
# 행의 개수와 열의 개수를 비교해서 행이 같거나 크면 행을 기준으로, 열이 크면 열을 기준으로 정렬
# 길이가 다를 경우 가장 긴 배열을 기준으로 모자란 길이를 0으로 채움
# 길이가 100을 넘어가면 100개 이후 무시
# (1 ≤ r, c, k ≤ 100) -> 1부터 시작함. 조심

# arr[r][c]의 값이 k가 되는 최소 시간, 100초가 넘더라도 안되면 -1
더보기

 

풀이

 

# from collections import Counter

def Counter(list):
    count_number = dict()

    for num in list:
        if num not in count_number:
            count_number[num] = 0

        count_number[num] += 1

    return count_number

def flipMatrix(arr):
    flip_arr = list(map(list, zip(*arr)))

    return flip_arr

def operateR(arr):
    row_count = len(arr)

    new_arr = [[] for _ in range(row_count)]

    max_len = 0

    # R 연산 수행
    for i in range(row_count):
        for item in sorted(Counter(arr[i]).items(), key=lambda x: (x[1], x[0])):
            if item[0] == 0:  # 0은 고려하지 않음.
                continue

            new_arr[i] += item

        max_len = max(len(new_arr[i]), max_len)

    if max_len > 100:
        max_len = 100

    # 크기 조절
    for i in range(row_count):
        if len(new_arr[i]) <= max_len:
            new_arr[i] += [0 for _ in range(max_len - len(new_arr[i]))]
        else: # 길이가 100보다 큰 경우
            new_arr[i] = new_arr[:100]

    return new_arr

def solution(r, c, k, arr):
    time = 0

    while time <= 100:
        # 행과 열 크기 비교
        row_count = len(arr)
        col_count = len(arr[0])

        # 조건 충족 시 return
        if r <= row_count - 1 and c <= col_count - 1 and arr[r][c] == k:
            return time

        if row_count >= col_count:
            # R연산 수행 후 크기 조절
            arr = operateR(arr)
        else:
            #C 연산 수행

            # 뒤집기
            arr = flipMatrix(arr)

            # R연산과 동일 계산 후 크기 조절
            arr = operateR(arr)

            # 뒤집기
            arr = flipMatrix(arr)

        time += 1

    # 100초가 지나면 -1 return
    return -1


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

print(solution(r - 1, c - 1, k, arr))

 


 

알게 된 점

 

python의 zip 함수

 

python의 zip 함수는 iterables의 요소들을 모으는 이터레이터를 만듭니다.

이게 무슨 소리냐 하면,

 

arr = [1, 2, 3]
arr2 = [4, 5, 6]

zip(arr, arr2) //[(1, 4), (2, 5), (3, 6)]

 

쉽게, 내부 요소들을 차례대로 짝지어서 묶어주는 함수가 zip 함수이다.

 

zip 함수를 이용한 배열 뒤집기

 

위의 zip 함수를 이용하면, 손쉽게 배열은 뒤집을 수 있다.

배열(리스트) 변수 앞에 *를 붙이면 내부 성분 요소들만 가져오는데,이를 zip 함수에 넣으면 다음과 같은 꼴이 된다.

 

arr = [[1, 2, 3], [4, 5, 6]]

*arr # [1, 2, 3], [4, 5, 6]

zip(*arr) == zip([1, 2, 3], [4, 5, 6])

 

즉, 이 그림과 같아진다.

 

zip 함수는 zip 객체를 반환하는데 내부에는 각 배열에서 묶인 성분들이 tuple로 존재한다.

tuple은 수정할 수 없기 때문에 용이하게 사용하기 위해, 아래와 같이 작성할 수 있다.

def flipMatrix(arr):
    flip_arr = list(map(list, zip(*arr)))

    return flip_arr

 

Github

 

GitHub - bh2980/Algorithm-Problem: 알고리즘 풀이 흔적들

알고리즘 풀이 흔적들. Contribute to bh2980/Algorithm-Problem development by creating an account on GitHub.

github.com