https://www.acmicpc.net/problem/1749
1749번: 점수따먹기
동주는 항상 혼자 노느라 심심하다. 하지만 혼자 놀기의 고수가 된 동주는 매일매일 게임을 개발하여 혼자놀기의 진수를 우리에게 보여준다. 어느 날 동주는 새로운 게임을 개발하였다. 바로 점
www.acmicpc.net
1. 난이도 골드4 (🥇)
https://www.acmicpc.net/problem/11660 (구간 합 구하기5) 2차원 배열을 이용한다는 점에서 이 문제와 유사하나,
(x1,y1)부터 (x2,y2)까지의 경우에 가능한 x1,y1을 모두 확인해봐야 한다는 차이점이 존재한다.
1. 새로운 배열에 구간합을 구한다.
sum_num[i][j] = sum_num[i-1][j] + sum_num[i][j-1] - sum_num[i-1][j-1] + num[i][j]
2. 끝점을 for문으로 완전탐색하고, 시작점(처음부터 끝점까지)도 for문으로 완전탐색해서 총 4중 for문을 이용한다.
for x1 in range(1,n+1):
for y1 in range(1,m+1):
for x2 in range(1,x1+1):
for y2 in range(1,y1+1):
test = sum_num[x1][y1] - sum_num[x1][y2-1] - sum_num[x2-1][y1] + sum_num[x2-1][y2-1]
3. 지나온 모든 부분행렬의 합 중, max를 출력하면 된다.
2. 내가 작성한 코드
import sys
input = sys.stdin.readline
n,m = map(int, input().rstrip().split())
num = [[0] * (m+1)]
for i in range(n):
num_row = [0] + list(map(int, input().rstrip().split()))
num.append(num_row)
sum_num = [[0] * (m+1) for _ in range(n+1)]
max_num = -10000
for i in range(1,n+1):
for j in range(1,m+1):
sum_num[i][j] = sum_num[i-1][j] + sum_num[i][j-1] - sum_num[i-1][j-1] + num[i][j]
for x1 in range(1,n+1):
for y1 in range(1,m+1):
for x2 in range(1,x1+1):
for y2 in range(1,y1+1):
test = sum_num[x1][y1] - sum_num[x1][y2-1] - sum_num[x2-1][y1] + sum_num[x2-1][y2-1]
max_num = max(max_num, test)
print(max_num)
아무리 봐도 로직의 개선이 필요할 것 같아서 구글링을 해보았고, 행과 열의 누적합을 달리해 값을 구하 방법을 찾았다.
[Python] 백준 1749 - 점수따먹기
분류: Prefix Sum (누적합)
velog.io
이 분의 글을 참고해서 문제를 해결하면 시간복잡도를 반절로 줄일 수 있다.
다른 분들의 코드를 참고하는데 C++ 이 8ms 인 걸 보고 C++ 도 한 번 공부해보면 좋겠다는 생각을 해봤삼,,
'🔅코딩테스트 공부🔅 > ❗백준' 카테고리의 다른 글
[백준] 14567번 선수과목(python) (0) | 2023.03.03 |
---|---|
[백준] 1197번 최소 스패닝 트리(python) (0) | 2023.03.02 |
[백준] 피아노 체조(python)(누적합) (0) | 2023.03.02 |
[백준] 20438번 출석체크(python)(누적합) (0) | 2023.03.02 |
[백준] 11659 구간 합 구하기 4(python)(누적합) (0) | 2023.03.01 |
댓글