문제
N×N개의 수가 N×N 크기의 표에 채워져 있다. (x1, y1)부터 (x2, y2)까지 합을 구하는 프로그램을 작성하시오. (x, y)는 x행 y열을 의미한다.
예를 들어, N = 4이고, 표가 아래와 같이 채워져 있는 경우를 살펴보자.
1 | 2 | 3 | 4 |
2 | 3 | 4 | 5 |
3 | 4 | 5 | 6 |
4 | 5 | 6 | 7 |
여기서 (2, 2)부터 (3, 4)까지 합을 구하면 3+4+5+4+5+6 = 27이고, (4, 4)부터 (4, 4)까지 합을 구하면 7이다.
표에 채워져 있는 수와 합을 구하는 연산이 주어졌을 때, 이를 처리하는 프로그램을 작성하시오.
입력
첫째 줄에 표의 크기 N과 합을 구해야 하는 횟수 M이 주어진다. (1 ≤ N ≤ 1024, 1 ≤ M ≤ 100,000) 둘째 줄부터 N개의 줄에는 표에 채워져 있는 수가 1행부터 차례대로 주어진다. 다음 M개의 줄에는 네 개의 정수 x1, y1, x2, y2 가 주어지며, (x1, y1)부터 (x2, y2)의 합을 구해 출력해야 한다. 표에 채워져 있는 수는 1,000보다 작거나 같은 자연수이다. (x1 ≤ x2, y1 ≤ y2)
출력
총 M줄에 걸쳐 (x1, y1)부터 (x2, y2)까지 합을 구해 출력한다.
예제 입력 1 복사
4 3
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
2 2 3 4
3 4 3 4
1 1 4 4
예제 출력 1 복사
27
6
64
예제 입력 2 복사
2 4
1 2
3 4
1 1 1 1
1 2 1 2
2 1 2 1
2 2 2 2
예제 출력 2 복사
1
2
3
4
[소스 코드1 - 시간 초과]
시간 초과 나올 거 알았지만 혹시나 해서 해본 코드이다.
역시나 시간 초과가 나오기에 시도도 안 하는 게 좋을 것 같다.
n, m = map(int, input().split())
arr = []
for i in range(n):
a = list(map(int, input().split()))
arr.append(a)
def sum_arr(x1, y1, x2, y2):
sum = 0
for row in range(x1-1, x2):
for col in range(y1-1, y2):
sum += arr[row][col]
return sum
for i in range(m):
x1, y1, x2, y2 = map(int, input().split())
result = sum_arr(x1, y1, x2, y2)
print(result)
[문제 풀이]
누적합을 이용해야 하는 문제이다.
누적합을 구하고 그 값을 다시 연산해서 내가 원하는 값을 구해야 하는 문제이다.
1 | 2 | 3 |
2 | 3 | 4 |
3 | 4 | 5 |
이러한 2차원 배열이 존재할 때 누적합을 나타내는 배열은 아래와 같다
1 | 1 + 2 | 1 + 2 + 3 |
1 + 2 | 1 + 2 + 2 +3 | 1 + 2 + 2 + 3 + 3 + 4 |
1 + 2 + 3 | 1 + 2 + 2 + 3 + 3 + 4 | 1 + 2 + 2+ 3 + 3 + 3 + 4 + 4 + 5 |
여기에서 (x1, y1), (x2, y2)가 주어졌을 때 우리는 x1행부터 x2행까지, y1열부터 y2열까지의 요소들의 합을 구해야 한다.
만일 (2, 2), (3, 3)이라고 할 때 아래와 같이 숫자가 쓰인 부분의 합만 구해야 한다.
3 | 4 | |
4 | 5 |
그러기 위해서는 누적합을 저장한 배열인 dp를 아래와 같은 방식으로 연산해야 한다.
[소스 코드2 - 맞았습니다!]
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
arr = []
for i in range(n):
a = list(map(int, input().split()))
arr.append(a)
dp = [[0]*(n+1) for i in range(n+1)]
for i in range(1, n+1):
for j in range(1, n+1):
dp[i][j] = dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1] + arr[i-1][j-1]
for k in range(m):
x1,y1,x2,y2 = map(int,input().split())
result = dp[x2][y2] - dp[x2][y1-1] -dp[x1-1][y2] + dp[x1-1][y1-1]
print(result)
'알고리즘 > python' 카테고리의 다른 글
[python/파이썬] 백준 11728 배열 합치기 (0) | 2022.05.09 |
---|---|
[python/파이썬] 백준 3029 경고 (0) | 2022.05.06 |
[python/파이썬] 백준 2294 동전 2 (0) | 2022.05.03 |
[python/파이썬] 백준 2156 포도주 시식 (0) | 2022.05.02 |
[python/파이썬] 백준 2753 윤년 (0) | 2022.04.30 |