15724번: 주지수
네모 왕국의 왕인 진경대왕은 왕국의 영토를 편하게 통치하기 위해서 1X1의 단위 구역을 여러 개 묶어서 하나의 거대 행정구역인 주지수(州地數, 마을의 땅을 셈)를 만들 예정이다. 진경대왕은
www.acmicpc.net
문제
네모 왕국의 왕인 진경대왕은 왕국의 영토를 편하게 통치하기 위해서 1X1의 단위 구역을 여러 개 묶어서 하나의 거대 행정구역인 주지수(州地數, 마을의 땅을 셈)를 만들 예정이다. 진경대왕은 주지수를 만들기 위해서 일정한 직사각형 범위 내에 살고 있는 사람 수를 참고 자료로 쓰고 싶어한다.

진경대왕은 굉장히 근엄한 왕이기 때문에 당신에게 4개의 숫자로 직사각형 범위를 알려줄 것이다.
예를 들어, 위와 같이 사람이 살고 있다고 가정할 때 <그림 1>의 직사각형 범위의 사람 수를 알고 싶다면 진경대왕은 네 개의 정수 1 1 3 2를 부를 것이다. 마찬가지로 <그림 2>는 1 1 1 4, <그림 3>은 1 1 4 4가 될 것이다.
진경대왕을 위하여 이 참고 자료를 만들어내는 프로그램을 작성해보자.
입력
첫째 줄에 영토의 크기 N, M(1 ≤ N, M ≤ 1,024)이 주어진다.
다음 N개의 줄에는 M개의 정수로 단위 구역 내에 살고 있는 사람 수가 주어진다. 각 단위 구역 내에 살고 있는 사람 수는 100명 이하이며, 각 단위 구역 별 최소 1명의 사람은 살고 있다.
그 다음 줄에는 진경대왕이 인구 수를 궁금해하는 직사각형 범위의 개수 K(1 ≤ K ≤ 100,000)가 주어진다.
다음 K개의 줄에는 네 개의 정수로 직사각형 범위 x1, y1, x2, y2가 주어진다(x1 ≤ x2, y1 ≤ y2).
출력
K개의 줄에 순서대로 주어진 직사각형 범위 내에 살고 있는 사람 수의 합을 출력한다.
코드
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
people = [[0] * (m+1) for _ in range(n+1)] # (1,1)부터 사람 수 누적합
for i in range(1, n+1):
arr = [0] + list(map(int, input().split()))
for j in range(1, m+1):
people[i][j] = people[i-1][j] + people[i][j-1] - people[i-1][j-1] + arr[j]
for _ in range(int(input())):
x1, y1, x2, y2 = map(int, input().split())
print(people[x2][y2] - people[x1-1][y2] - people[x2][y1-1] + people[x1-1][y1-1])
매번 sum 계산을 한다던가 하면 매우 비효율적일 것이므로 누적합을 미리 구하여 처리한다.
people 배열의 각 칸에는 (1,1)부터 그 칸까지 직사각형의 누적합을 구해둔다. 그리고 질문이 들어오면 다음과 같은 식으로 답을 구해준다.
people[x2][y2] - people[x1-1][y2] - people[x2][y1-1] + people[x1-1][y1-1]
예를 들어, N = 4, M = 7일 때 (3,3)에서 (4,5)까지의 직사각형의 범위 안의 사람들 수를 구한다고 할 때 그림으로 나타내보면 다음과 같다. 계산의 편의를 위해 0행과 0열을 넣었다.
(1,1)부터 (4,5)까지 직사각형(보라)에서 구하지 않는 부분(빨강, 파랑)을 빼주고 중복으로 빠진 부분(보라)은 한 번 더해주는 것이다.

한 장으로 나타내보면 아래와 같다.

'문제풀이 > 누적합' 카테고리의 다른 글
[Python/파이썬] 백준 1749번 점수따먹기 (0) | 2023.05.12 |
---|---|
[Python/파이썬] 백준 2015번 수들의 합 4 (0) | 2023.05.10 |
[Python/파이썬] 백준 21318번 피아노 체조 (0) | 2023.03.24 |
[Python/파이썬] 백준 11660번 구간 합 구하기 5 (0) | 2023.03.24 |
[Python/파이썬] 백준 20438번 출석체크 (0) | 2023.03.23 |
15724번: 주지수
네모 왕국의 왕인 진경대왕은 왕국의 영토를 편하게 통치하기 위해서 1X1의 단위 구역을 여러 개 묶어서 하나의 거대 행정구역인 주지수(州地數, 마을의 땅을 셈)를 만들 예정이다. 진경대왕은
www.acmicpc.net
문제
네모 왕국의 왕인 진경대왕은 왕국의 영토를 편하게 통치하기 위해서 1X1의 단위 구역을 여러 개 묶어서 하나의 거대 행정구역인 주지수(州地數, 마을의 땅을 셈)를 만들 예정이다. 진경대왕은 주지수를 만들기 위해서 일정한 직사각형 범위 내에 살고 있는 사람 수를 참고 자료로 쓰고 싶어한다.

진경대왕은 굉장히 근엄한 왕이기 때문에 당신에게 4개의 숫자로 직사각형 범위를 알려줄 것이다.
예를 들어, 위와 같이 사람이 살고 있다고 가정할 때 <그림 1>의 직사각형 범위의 사람 수를 알고 싶다면 진경대왕은 네 개의 정수 1 1 3 2를 부를 것이다. 마찬가지로 <그림 2>는 1 1 1 4, <그림 3>은 1 1 4 4가 될 것이다.
진경대왕을 위하여 이 참고 자료를 만들어내는 프로그램을 작성해보자.
입력
첫째 줄에 영토의 크기 N, M(1 ≤ N, M ≤ 1,024)이 주어진다.
다음 N개의 줄에는 M개의 정수로 단위 구역 내에 살고 있는 사람 수가 주어진다. 각 단위 구역 내에 살고 있는 사람 수는 100명 이하이며, 각 단위 구역 별 최소 1명의 사람은 살고 있다.
그 다음 줄에는 진경대왕이 인구 수를 궁금해하는 직사각형 범위의 개수 K(1 ≤ K ≤ 100,000)가 주어진다.
다음 K개의 줄에는 네 개의 정수로 직사각형 범위 x1, y1, x2, y2가 주어진다(x1 ≤ x2, y1 ≤ y2).
출력
K개의 줄에 순서대로 주어진 직사각형 범위 내에 살고 있는 사람 수의 합을 출력한다.
코드
import sys input = sys.stdin.readline n, m = map(int, input().split()) people = [[0] * (m+1) for _ in range(n+1)] # (1,1)부터 사람 수 누적합 for i in range(1, n+1): arr = [0] + list(map(int, input().split())) for j in range(1, m+1): people[i][j] = people[i-1][j] + people[i][j-1] - people[i-1][j-1] + arr[j] for _ in range(int(input())): x1, y1, x2, y2 = map(int, input().split()) print(people[x2][y2] - people[x1-1][y2] - people[x2][y1-1] + people[x1-1][y1-1])
매번 sum 계산을 한다던가 하면 매우 비효율적일 것이므로 누적합을 미리 구하여 처리한다.
people 배열의 각 칸에는 (1,1)부터 그 칸까지 직사각형의 누적합을 구해둔다. 그리고 질문이 들어오면 다음과 같은 식으로 답을 구해준다.
people[x2][y2] - people[x1-1][y2] - people[x2][y1-1] + people[x1-1][y1-1]
예를 들어, N = 4, M = 7일 때 (3,3)에서 (4,5)까지의 직사각형의 범위 안의 사람들 수를 구한다고 할 때 그림으로 나타내보면 다음과 같다. 계산의 편의를 위해 0행과 0열을 넣었다.
(1,1)부터 (4,5)까지 직사각형(보라)에서 구하지 않는 부분(빨강, 파랑)을 빼주고 중복으로 빠진 부분(보라)은 한 번 더해주는 것이다.

한 장으로 나타내보면 아래와 같다.

'문제풀이 > 누적합' 카테고리의 다른 글
[Python/파이썬] 백준 1749번 점수따먹기 (0) | 2023.05.12 |
---|---|
[Python/파이썬] 백준 2015번 수들의 합 4 (0) | 2023.05.10 |
[Python/파이썬] 백준 21318번 피아노 체조 (0) | 2023.03.24 |
[Python/파이썬] 백준 11660번 구간 합 구하기 5 (0) | 2023.03.24 |
[Python/파이썬] 백준 20438번 출석체크 (0) | 2023.03.23 |