1034번: 램프
첫째 줄에 N과 M이 주어진다. N은 행의 개수이고, M은 열의 개수이다. N과 M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 램프의 상태가 주어진다. 1이 켜져있는 상태이고, 0이 꺼져
www.acmicpc.net

알고리즘 공부를 시작한지 얼마 안되어서 생각보다 어렵게 느껴지네요. 어쨌든 제가 이해한 풀이대로 적어보도록 하겠습니다.
1 0 1
1 0 0
1 0 1
K=3 인 예제를 가지고 설명해보겠습니다.
1. 각 행마다 0의 개수를 구합니다. 예제에서는 1행은 1개, 2행은 2개, 3행은 1개가 됩니다.
2. (0의 개수가 K보다 작거나 같고), (K가 짝수면 0의 개수도 짝수, K가 홀수면 0의 개수도 홀수) 여야 한 행을 온전히 모두 킨 상태로 만들 수 있습니다.
생각해보면 당연합니다.
0의 개수가 스위치를 누르는 횟수인 K보다 많으면 절대로 꺼져있는 램프들을 다 못킵니다. 그리고 0의 개수가 1개인데 K가 2일 경우 어떤 스위치를 2번 누르던 행을 모두 킬 수 없겠죠? 따라서 (0의 개수 <= K의 개수) and (0의 개수%2 == K%2)를 만족하는 행만 행에 있는 모든 램프를 킬 수 있습니다.
3. 한 행의 모든 램프를 킬 수 있다면, 이 행과 똑같이 생긴 다른 행도 킬 수 있으므로 똑같은 값을 가진 행들의 개수를 구합니다. 예제에서는 첫번째 행 1 0 1은 0의 개수가 K의 개수인 3보다 작고, 0의 개수와 K가 홀수이므로 이 행은 모두 킬 수 있습니다. 따라서 값이 같은 1행과 3행을 동시에 킬 수 있습니다. 따라서 총 2개의 행을 킬 수 있습니다.
두번째 행을 생각해보면 K는 홀순데 0의 개수는 짝수이므로 이 행은 킬 수 없습니다.
이와 같이 모든 행에 대해 반복하면서 어떤 행을 모두 킬 수 있다면 그 행과 똑같은 값을 가진 행의 개수들을 세고 센 값들 중 최대값을 구하면 정답이 됩니다!
구현한 코드는 다음과 같습니다.
# 입력받기
n, m = tuple(map(int, input().split()))
lst = []
for _ in range(n):
lst.append(input())
k = int(input())
max_cnt = 0
# 모든 행에 대해 반복
for col in range(n):
# 0의 개수 세기
zero_count = 0
for num in lst[col]:
if num == '0':
zero_count += 1
# 이 행과 똑같은 값을 가진 행의 개수 세기
col_light_cnt = 0
if zero_count <= k and zero_count%2 == k%2: # 이 행을 모두 킬 수 있다면
for col2 in range(n): # 다시한번 행을 반복하면서
if lst[col] == lst[col2]: # 두 개의 행이 같으면
col_light_cnt += 1 # 1을 더해준다
max_cnt = max(max_cnt, col_light_cnt) # 최대값보다 크면 업데이트
print(max_cnt)

'파이썬' 카테고리의 다른 글
파이썬 순열, 조합 스택으로 구현하기 (1) | 2022.03.29 |
---|---|
파이썬 pyautogui와 키보드 후킹을 통한 자동 클릭 매크로 (0) | 2021.02.24 |
파이썬 키보드 후킹을 통한 pyautogui 제어 (2) | 2021.02.16 |