[문제 링크] 👇
풀이
💡 슬라이싱, 행 열 변환, sum(), max() 이용
📌 각 행, 열의 합 구하는 방법
for i in range(100):
sum_num = sum(board[i][:])
- [ : ]
- 모든 인덱스를 슬라이싱 한다.
- [5 : ] = 5부터 끝까지 슬라이싱, [5 : 7] = 5부터 6까지 슬라이싱, [ : 8] = 처음부터 7까지 슬라이싱
- sum(board[i][:])
- i가 0부터 99까지 움직이므로 각 행의 전체를 가져와서 합계를 구한다.
📌 행 열을 서로 변경하는 방법
new_board = list(map(list, zip(*board)))
- zip(*board)
- zip은 여러 개의 이터러블(iterable, 반복 가능한 객체)을 병렬로 묶어서 각 위치에 있는 요소들을 튜플(tuple)로 반환한다.
- 여기서 *board는 리스트 board의 각 행을 개별적으로 zip에 전달하는 역할을 한다. 즉, *board는 board의 모든 행을 각각의 인자로 전달한다.
- zip(*board)의 결과는 각 열을 튜플로 묶은 이터레이터가 된다.
- map(list, zip(*board))
- zip(*board)의 결과는 튜플이므로, 이를 리스트로 변환해야 한다.
- map(list, zip(*board))는 zip(*board)의 각 튜플을 list로 변환하여 이터레이터로 반환한다.
- list(map(list, zip(*board))):
- map의 결과는 이터레이터이기 때문에, list()로 감싸 최종적으로 list 객체로 변환한다.
- 최종 결과는 행과 열이 전환된 2차원 리스트가 된다.
📌 최댓값 구하는 방법
result = max(row_max, col_max, dia_max)
- row_max, col_max, dia_max
- 행의 합 중에서 최댓값, 열의 합 중에서 최댓값, 대각선의 합 중에서 최댓값이다.
- max()
- 최댓값을 반환하는 파이썬의 내장 함수다.
- 인자로 정수를 전달하면 최댓값을 반환한다.
Solution
def calc(board):
max_sum = 0
for i in range(100):
sum_num = sum(board[i][:]) # 0~99 인덱스의 전체 합 구하기
max_sum = max(sum_num, max_sum) # 합계의 최댓값 구하기
return max_sum
def diagonal(board):
right_sum, left_sum = 0, 0
for i in range(100):
right_sum += board[i][i] # 오른 대각
left_sum += board[i][99 - i] #왼 대각
return max(right_sum, left_sum)
for _ in range(10):
test_case = int(input())
board = [list(map(int, input().split())) for _ in range(100)]
row_max = calc(board) # 행의 합
# 행 열 변환 후 열의 합
new_board = list(map(list, zip(*board)))
col_max = calc(new_board)
# 대각선 최댓값
dia_max = diagonal(board)
result = max(row_max, col_max, dia_max)
print(f"#{test_case} {result}")
코드의 효율성과 가독성 문제 때문에 다음과 같이 수정한다.
수정 포인트
- calc 함수에서 전체 합 계산 방식 단순화
- sum(board[i][:]) 대신 sum(board[i])로도 같은 효과를 얻을 수 있다. 리스트의 전체를 대상으로 슬라이싱 [:]을 사용하는 대신, 리스트 자체를 sum에 전달해도 무방하다.
- diagonal 함수의 중복된 max 구문 제거
- 현재 대각선의 합 중 큰 값을 반환하는 부분에서 max 함수를 사용하고 있다. 하지만 호출부에서 이미 최대값을 비교하고 있으므로 diagonal 함수는 두 대각선의 합을 구하기만 하고, result = max(row_max, col_max, right_sum, left_sum)로 최대값을 결정할 수 있.
- 주석을 추가하여 코드 가독성 향상
- 각 섹션에 대해 명확한 주석을 달면 가독성을 높일 수 있다.
- 최종적으로 최대값을 반환할 때 대각선 합의 두 가지 값을 명시적으로 전달
- diagonal 함수가 두 값을 반환하게 변경하고, 호출부에서 최종 max 비교를 할 수 있도록 한다.
최적화된 코드
def calc(board):
max_sum = 0
# 각 행의 합을 계산하여 최대값 찾기
for i in range(100):
sum_num = sum(board[i]) # 각 행의 합 구하기
max_sum = max(sum_num, max_sum) # 현재 행 합계와 최대값 비교
return max_sum
def diagonal(board):
right_sum, left_sum = 0, 0
# 오른쪽 대각선과 왼쪽 대각선의 합을 구하기
for i in range(100):
right_sum += board[i][i] # 오른쪽 대각선
left_sum += board[i][99 - i] # 왼쪽 대각선
return right_sum, left_sum
# 테스트 케이스 실행
for _ in range(10):
test_case = int(input())
board = [list(map(int, input().split())) for _ in range(100)]
# 행의 최대 합
row_max = calc(board)
# 행과 열을 변환한 새로운 배열을 이용하여 열의 최대 합
col_max = calc(list(map(list, zip(*board))))
# 대각선의 두 합
right_sum, left_sum = diagonal(board)
# 모든 최대값 중 가장 큰 값
result = max(row_max, col_max, right_sum, left_sum)
print(f"#{test_case} {result}")
👩💻 회고
데이터가 너무 많은 거 빼고는 쉽게 풀 수 있었다. 각자 함수를 따로 나눠서 계산해서 보기에도 편한 것 같다.
가독성과 불필요한 코드가 조금 들어가 있었지만 꽤 잘 푼 것 같다.
'SWEA' 카테고리의 다른 글
[SWEA] 3142. 영준이와 신비한 뿔의 숲 (Python/D3) (0) | 2024.10.26 |
---|---|
[SWEA] 10200. 구독자 전쟁 (Python/D3) (0) | 2024.10.26 |
[SWEA] 14692. 통나무 자르기 (Python/D3) (0) | 2024.10.25 |
[SWEA] 1216. [S/W 문제해결 기본] 3일차 - 회문2 (Python/D3) (0) | 2024.10.25 |
[SWEA] 6692. 다솔이의 월급 상자 (Python/D3) (0) | 2024.10.24 |