본문 바로가기

알고리즘/백준 문제 풀이

[Python] 9718번 Matrix Transformation

728x90

https://www.acmicpc.net/problem/9718

 

9718번: Matrix Transformation

The first input line contains a positive integer,n, indicating the number of matrices (test cases). Each matrix starts with a line containing R(2≤R≤30) and C(2≤C≤30) separated by a single space. Each of the next R lines contains C integers. Each of

www.acmicpc.net


 

23/03/14

 

 

불변량의 개념을 숙지한 상태라면 쉽게 접근할 수 있는 문제이다.

 

만약 이 문제를 크기 제한($2 \leq R \leq 30$)만 보고 브루트포스나 그리디적으로 직접 시뮬레이션 돌려가며 구현할 생각을 했다면 시간초과가 날 것이다.


 

문제 접근 방식:

 

 

먼저, 어떤 변환을 했을 때에도 항상 변하지 않는 값이 있는지 찾아보자.

 

한 가지 관찰할 수 있는 사실은, 행렬을 체스판처럼 검은색과 흰색으로 칠한 뒤에, 두 인접한 칸을 잡으면, 그 두 칸은 항상 검은 칸과 흰색 칸이라는 사실을 알 수 있다.

 

다시 말해, $(i, j)$칸이 있을 때, $(i+j) \ mod \ 2 \ = 0$이 되는 칸을 흰색 칸, $(i+j) \ mod \ 2 \ = 1$이 되는 칸을 검은 칸이라고 하면, 임의의 두 인접한 칸은 항상 흰색 칸과 검은 칸이 된다는 사실을 알 수 있다.

 

때문에 우리가 하는 행동은, 흰색 칸 하나와 검은 칸 하나 각각에 $1$을 더하거나 빼는 것과 같다.

 

 

이를 통해 알 수 있는 것은, (흰색 칸 숫자의 총합) - (검은색 칸 숫자의 총합)은 행동 이후에도 항상 변하지 않는다는 사실이다.

 

문제에서는 행동의 반복을 통해 영행렬을 만들 수 있는지의 여부를 묻고있다.

 

따라서, 초기 상태에서 영행렬과 같이 (흰색 칸 숫자의 총합) - (검은 색 칸 숫자의 총합) $=$ $0$이 되는지의 여부만 체크해주면 해결할 수 있다.


아래는 내가 위의 접근 방식과 같이 작성한 파이썬 코드이다. 더보기를 누르면 확인할 수 있다.

더보기
# 9718번 Matrix Transformation
# 수학, 애드혹, 불변량
'''
접근 방법:
(i, j)칸이 있을 때, 이 칸의 위치를 i+j라고 하자.
그러면 i+j가 홀수가 되는 칸과 짝수가 되는 칸으로 임의의 칸을 분류할 수 있다.
두 인접한 칸을 잡으면, 항상 그 두 칸은 i+j가 홀수가 되는 칸과
짝수가 되는 칸이므로, 그 두 칸에 모두 1을 빼거나 더해도,
(홀수칸 숫자의 총합) - (짝수칸 숫자의 총합)은 항상 변하지 않는다.
따라서, 초기 상태에서 (홀수칸 숫자의 총합) - (짝수칸 숫자의 총합)이
0이 되는지만 판단해주면 영행렬을 만들 수 있는지 판단할 수 있다.
'''
import sys
input = sys.stdin.readline

def matrix_can_change_into_zero_matrix(matrix, row, col):  # 행렬과 행렬 크기를 인자로 받음.
    odd_sum = 0
    even_sum = 0
    for r in range(row):
        for c in range(col):
            if (r+c)%2 == 0:
                even_sum += matrix[r][c]
            else:
                odd_sum += matrix[r][c]
    if odd_sum - even_sum == 0:
        return True
    else:
        return False
                                
T = int(input())  # 테스트 케이스 개수
for _ in range(T):
    row, col = map(int, input().rstrip().split())
    matrix = [list(map(int, input().rstrip().split())) for _ in range(row)]
    print('YES' if matrix_can_change_into_zero_matrix(matrix, row, col) else 'NO')

'알고리즘 > 백준 문제 풀이' 카테고리의 다른 글

[Python] 27306번 DAGame  (0) 2023.05.04
[Python] 9066번 금고  (0) 2023.03.21
[Python] 2758번 로또  (0) 2023.03.13
[Python] 1563번 개근상  (0) 2023.03.13
[Python] 1229번 육각수  (0) 2023.03.13