728x90
🔗 문제 링크
11660번: 구간 합 구하기 5
첫째 줄에 표의 크기 N과 합을 구해야 하는 횟수 M이 주어진다. (1 ≤ N ≤ 1024, 1 ≤ M ≤ 100,000) 둘째 줄부터 N개의 줄에는 표에 채워져 있는 수가 1행부터 차례대로 주어진다. 다음 M개의 줄에는 네
www.acmicpc.net
💡 문제 풀이 및 해석
- 누적합 문제로써 매번 계산하면 안 되는 문제다.
- 이미 누적이 된 상태에서 상수시간으로 각각의 케이스를 해결해야 한다.
- 수학적으로 부분구역은
acc [ey][ex] + acc [sy - 1][sx - 1] - acc[sy - 1][ex] - acc [ey][sx - 1]
이미 누적된 데이터만 있으면 상수 시간 안에 해결이 가능하다. - 누적된 데이터는
acc [y][x]=myMap [y][x]+acc [y-1][x]+acc [y][x-1]-acc [y-1][x-1]으로
현재값에서 누적된 위아래 값을 더해주고, 왼쪽 위의 누적값을 빼주면 누적된 데이터가 나온다.
⭐️ 정답 코드 및 설명
#include <iostream>
using namespace std;
int N, M, sx, sy, ex, ey;
int myMap[1025][1025];
int acc[1025][1025];
void accMap(int x, int y){
acc[y][x]=myMap[y][x]+acc[y-1][x]+acc[y][x-1]-acc[y-1][x-1];
}
void makeAccMap(){
for(int y = 1; y <= N; y++){
for(int x = 1; x <= N; x++){
accMap(x, y);
}
}
}
void input(){
ios_base::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL);
cin >> N >> M;
for(int y = 1; y <= N; y++){
for(int x = 1; x <= N; x++){
cin >> myMap[y][x];
}
}
makeAccMap();
}
int main() {
input();
for(int i = 0; i < M; i++){
cin >> sy >> sx >> ey >> ex;
cout << acc[ey][ex] + acc[sy - 1][sx - 1] - acc[sy - 1][ex] - acc[ey][sx - 1] << "\n";
}
return 0;
}
🤔 문제 후기
누적합으로 문제를 풀라고 대놓고 되어 있었는데, 실제로 수학적인 배경 지식이 있다면 어렵지 않은 문제였다.
728x90
'문제풀이 > 알고리즘 문제 풀이' 카테고리의 다른 글
[ 백준 11054 ] 가장 긴 바이토닉 부분 수열 (C++) - DP, 브루트포스 (0) | 2024.05.14 |
---|---|
[ 백준 14728 ] 벼락치기 (C++) - DP, KnapSack (0) | 2024.04.25 |
[ 백준 2531 ] 회전 초밥 (C++) - 투 포인터 (0) | 2024.04.23 |
[ 백준 12100 ] 2048 Easy (C++) - DFS, 브루트포스, 구현 (0) | 2024.04.23 |
[ 백준 4485 ] 녹색 옷 입은 애가 젤다지? (C++) - 다익스트라 (0) | 2024.04.22 |