-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path1455.py
61 lines (51 loc) · 2.99 KB
/
1455.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'''
풀이
주어진 동전판의 마지막 칸부터 역순으로 뒷면인 동전들을 뒤집으면
뒤집는 최소 횟수를 보장하는 그리디 알고리즘이다.
m, n의 최대 범위가 100이므로 동전을 뒤집을 때마다 동전의 상태를 기록하게 되면
대략 시간 복잡도가 n^2 * m^2이 되어 시간초과 우려가 있다.
그래서, 처음에는 뒤집을 때의 규칙성을 찾기 위해 많은 시간을 소모했다.
하지만 규칙성을 찾는데 실패했고, 동전 상태 기록을 최소화시킬 방법을 찾아 풀이했다.
동전판의 열에 대해 각각 뒤집은 누적 횟수를 구하여 현재 위치의 동전 상태를 결정하는 방법이다.
현재 위치의 동전에 대해 해당 경우를 나누어보면 다음과 같다.
1. 현재 위치의 동전이 앞면일 때
뒤집은 누적 횟수가 짝수 -> 앞면을 유지하므로 뒤집지 않는다.
뒤집은 누적 횟수가 홀수 -> 뒷면이 되므로 뒤집는 횟수 1 추가
2. 현재 위치의 동전이 뒷면일 때
뒤집은 누적 횟수가 짝수 -> 뒷면이 되므로 뒤집는 횟수 1 추가
뒤집은 누적 횟수가 홀수 -> 앞면이 되므로 뒤집지 않는다.
예를 들어 다음과 같은 동전판이 있을 때 위 과정을 수행해보자.
1 0 0
0 0 1
1 0 1
뒤집은 횟수를 기록할 동전판 열크기의 배열 A = [0, 0, 0]
맨 마지막 요소부터 역순으로 진행할 때
1. 2행 (초기 상태(0, 0, 0))
1 -> A = [0 +1, 0 +1, 0 +1] (짝수번(0) 뒤집혀 1이므로 뒤집는다.)
0 -> A = [1 +1, 1 +1, 1] (홀수번 뒤집혀 1이므로 뒤집는다.)
1 -> A = [2 +1, 2, 1] (짝수번 뒤집혀 1이므로 뒤집는다.)
2. 1행 (2행의 상태(3, 2, 1)를 가져와서 수행한다.)
1 -> A = [3, 2, 1] (홀수번 뒤집혀 0이므로 뒤집지 않는다.)
0 -> A = [3, 2, 1] (짝수번 뒤집혀 0이므로 뒤집지 않는다.)
0 -> A = [3 +1, 2, 1] (홀수번 뒤집혀 1이므로 뒤집는다.)
3. 0행 (1행의 상태(4, 2, 1)를 가져와서 수행한다.)
0 -> A = [4 +1, 2 +1, 1 +1] (홀수번 뒤집혀 1이므로 뒤집는다.)
0 -> A = [5 +1, 3 +1, 2] (홀수번 뒤집혀 1이므로 뒤집는다.)
1 -> A = [6 +1, 4, 2] (짝수번 뒤집혀 1이므로 뒤집는다.)
따라서, 총 7번 뒤집어야 한다.
풀이 코드는 위 과정을 각 열에 기록하지 않고 증가 횟수만 기록 후 합해서 누적 카운트를 구하도록 하였다.
'''
def solution():
n, m = map(int, input().split())
coins = [input() for _ in range(n)]
cnt = [0] * m
for i in range(n - 1, -1, -1):
for j in range(m - 1, -1, -1):
cur = sum(cnt[j:])
if coins[i][j] == '1':
cnt[j] += [1, 0][cur & 1]
else:
cnt[j] += [0, 1][cur & 1]
print(sum(cnt))
if __name__ == '__main__':
solution()