Algorithm

백준 1236, 5533

김디니 2022. 8. 3. 16:47

1236 성 지키기

성의 크기와 경비원이 어디있는지 주어졌을 때, 몇 명의 경비원을 최소로 추가해야 영식이를 만족시키는지 구하는 프로그램을 작성하시오.

n, m = map(int, input().split())
matrix = []
row_cnt = 0
col_cnt = 0

for _ in range(n):
    line = list(input())
    matrix.append(line)

for i in range(n):
    if 'X' not in matrix[i] :
        row_cnt += 1

for j in range(m):
    if "X" not in [matrix[i][j] for i in range(n)]:        
        col_cnt += 1

print(max(row_cnt, col_cnt))
# 입력값
3 5
XX...
.XX..
...XX

이러한 형식의 입력값이 주어졌을 때 추가해야 할 경비원의 수를 구한다. 

행렬에서 하나의 X가 있을 경우 추가해야 할 경비원은 0이다. 

하나의 행 혹은 열이 모두 '.'일 경우 1명의 경비원을 추가한다. 

 

위 코드를 큰 구조로 나눠보자면, 

1. 반복문으로 입력값을 받고

2. 각 행에 'X'가 없을 경우 경비원 1명 추가 

3. 각 열의 'X'가 없을 경우 경비원 1명 추가 

 

# 행 탐색
for i in range(n):
    if 'X' not in matrix[i] :
        row_cnt += 1

i는 matrix의 행, 가로를 탐색한다. 

즉, 입력값을 입력 시 나열한 값들을 하나의 리스트로 묶어서 해당 리스트를 탐색하는 것이다. 

만약 행에 'X'가 없으면 row_cnt에 1을 추가한다. 

해당 행에 경비원(X)이 한명이라도 없어야 row_cnt에 추가할 수 있다. 

i and j 탐색 방향

 

# 열 탐색
for j in range(m):
    if "X" not in [matrix[i][j] for i in range(n)]:        
        col_cnt += 1

위의 이미지처럼 j는 열을 탐색한다. 

행 탐색과 다르게 행렬의 좌표를 기입하여 하나씩 탐색한다. 

matrix[i][j]에서 j를 기준으로 i가 계속해서 바뀌게 된다. 

열(j) 탐색

현재 j는 1이므로 각 리스트의 인덱스 1의 위치를 세로로 탐색한다. 

인덱스 1의 값인 'X', 'X', '.' 를 탐색한 것을 확인할 수 있다. 

 

print(max(row_cnt, col_cnt))

행과 열을 탐색하였으므로 중복되지 않도록 row_cnt와 col_cnt 중 큰 수를 출력한다. 

 

5533 유니크

각 플레이어는 1이상 100 이하의 정수를 카드에 적어 제출한다. 각 플레이어는 자신과 같은 수를 쓴 사람이 없다면, 자신이 쓴 수와 같은 점수를 얻는다. 만약, 같은 수를 쓴 다른 사람이 있는 경우에는 점수를 얻을 수 없다.

n = int(input())
score = [[], [], []]
sum = []                                    # 각 최종 점수 저장소
 
for i in range(n):
    a, b, c = map(int, input().split())
    score[0].append(a)                      # 첫 번째 점수 저장소
    score[1].append(b)                      # 두 번째 점수 저장소
    score[2].append(c)                      # 세 번째 점수 저장소 
    
for i in range(n):
    get = 0                                 # 임시적으로 합계점수를 넣을 저장소 
    for j in range(3):
        if score[j].count(score[j][i]) == 1: # 각자 적은 점수가 유일하다면 
            get += score[j][i]              # 해당 점수를 get에 저장
    sum.append(get)                         # 최종 점수를 sum 리스트에 저장

for i in sum:                               # 각 최종 점수를 순차적으로 출력 
    print(i)
# 입력값
5
100 99 98
100 97 92
63 89 63
99 99 99
89 97 98

N명의 플레이어들이 각 3번의 점수를 적었을 때 

각 행은 각 플레이어들이 낸 점수들이며

각 열을 통해 각 플레이어들의 점수를 비교한다. 

 

이를 위해 각 플레이어들의 3개의 점수를 하나의 리스트로 보았을 때 

각 플레이어들의 첫 번째 점수, 두 번째 점수, 세 번째 점수를 3개의 리스트에 나눠서 저장하여 비교한다. 

해당 점수가 중복되었을 경우 count되지 않고, 유일한 점수라면 점수는 변수에 저장된다. 

최종적으로 변수에 저장된 점수를 각 플레이어별로 리스트에 저장하여 출력한다. 

 

 

for i in range(n):
    a, b, c = map(int, input().split())
    score[0].append(a)                      # 첫 번째 점수 저장소
    score[1].append(b)                      # 두 번째 점수 저장소
    score[2].append(c)                      # 세 번째 점수 저장소

값을 입력 받을 때 각 플레이어들의 1, 2, 3번째 점수를 3개의 리스트에 저장한다. 

for i in range(n):
    get = 0                                 # 임시적으로 합계점수를 넣을 저장소 
    for j in range(3):
        if score[j].count(score[j][i]) == 1: # 각자 적은 점수가 유일하다면 
            get += score[j][i]              # 해당 점수를 get에 저장
    sum.append(get)                         # 최종 점수를 sum 리스트에 저장

유일한 점수일 때 임시적으로 get 변수에 점수를 저장한다. 

i와 j의 탐색 방향

for문의 j는 계속 값을 바꾸며 탐색한다. 

3개의 리스트에서 0부터 4까지는 i의 값이고, 

각 리스트의 0, 1, 2, 3, 4 값을 세로로 인식하는 것은 j이다. 

 

즉, i가 1이고 j가 0일 때 현재 값은 100이다. 

score[1][0] == 100,

score[1][1] == 97,

score[1][2] == 92

 

i는 각 리스트의 인덱스 위치이고, j는 1에 해당하는 값을 세로로 탐색하였다. 

score[1][2]는 값이 92이고, 같은 리스트의 값 (양 옆의 값)을 비교하였을 때 92는 유일한 점수이므로 get에 저장되고, 최종적으로 sum 리스트의 인덱스 1의 위치에 저장된다. 

 

이 과정을 모두 거치고 마지막 for문을 통해 sum 리스트에 저장된 플레이어들의 최종 점수를 하나씩 출력한다. 

 

'Algorithm' 카테고리의 다른 글

[이론] 스택 Stack, 큐 Queue  (0) 2022.08.06
백준 1652 누울 자리를 찾아라  (1) 2022.08.04
백준 1269, 2750, 5063, 11286 / 프로그래머스 81301  (1) 2022.08.02
백준 2161, 2902, 9012  (0) 2022.08.01
백준 1292, 1357, 5622  (0) 2022.07.31