2022. 8. 12. 10:23ㆍAlgorithm/백준
class : 4
level : silver 2
문제 링크 : 구간 합 구하기 5
11660번: 구간 합 구하기 5
첫째 줄에 표의 크기 N과 합을 구해야 하는 횟수 M이 주어진다. (1 ≤ N ≤ 1024, 1 ≤ M ≤ 100,000) 둘째 줄부터 N개의 줄에는 표에 채워져 있는 수가 1행부터 차례대로 주어진다. 다음 M개의 줄에는 네
www.acmicpc.net
My Solution
let fs = require('fs');
let input = fs.readFileSync('/dev/stdin').toString().trim();
input = input.split('\n');
const [N, M] = input.shift().split(' ').map(Number);
let matrix = input.slice(0,N).map(str=>str.split(' ').map(Number));
input = input.splice(N).map(str=>str.split(' ').map(Number));
let answer = '';
let dp = new Array(N);
/// 2d array deep copy
matrix.forEach((val,ind)=>{
dp[ind] = val.slice(0);
});
matrix.forEach((arr,index) => {
arr.forEach((item, i)=>{
dp[index][i] = item ;
if(i!==0) dp[index][i] += dp[index][i-1];
if(index!==0)dp[index][i] += dp[index-1][i];
if(i!==0 && index!==0)dp[index][i]-=dp[index-1][i-1];
})
})
input.forEach(([x1,y1,x2,y2])=>{
let sum = dp[x2-1][y2-1];
if (x1 !== 1) sum -= dp[x1 - 2][y2 - 1];
if (y1 !== 1) sum -= dp[x2 - 1][y1 - 2];
if (x1 !== 1 && y1 !== 1) sum += dp[x1 - 2][y1 - 2];
answer+=`${sum}\n`;
})
console.log(answer.trim());
풀이방법
이 문제는 Dynamic Programming을 이용하여 푸는 문제이다.
dp라는 2D Array를 input으로 주어진 N x N matrix로 변환한다.(deep copy이용)
dp의 각 위치에는 (1,1)부터 (x,y)만큼의 값들의 합을 값으로 한다.
이후 (x2,y2)의 위치의 값에서 x1!==1인 경우 dp[x1 - 2][y2 - 1]을 빼고 y1!==1인 경우 dp[x2 - 1][y1 - 2]을 빼며 두 조건을 모두 만족하는 경우에 중복해서 빼준 dp[x1 - 2][y1 - 2]을 더해줍니다.
느낀점
두 가지 부분에서 고치는 데 어려움을 겪었다.
한 가지는 이전부터 (x,y)의 좌표를 무조건 적으로 columns는 x로, row는 y로 계산하던 버릇덕분에 어디서 틀렸는지 계속 고생하였다.
다른 한 가지는 2D Array의 deep copy 부분이었다. 나는 완전한 deep copy가 아닌 slice 메서드를 이용한 불완전한 deep copy하고 있었기에 중간 계산에서 계속 오류가 발생했다.
deep copy부분은 제 다른 글을 참고해 주시면 감사하겠습니다.(https://hopedevelopment.tistory.com/50)
'Algorithm > 백준' 카테고리의 다른 글
[JavaScript] 백준 1074 : Z (1) | 2022.09.29 |
---|---|
[JavaScript] 백준 11725 : 트리의 부모 찾기 (0) | 2022.09.02 |
[JavaScript] 백준 11053 : 가장 긴 증가하는 부분 수열 (0) | 2022.08.11 |
[JavaScript] 백준 1149 : RGB거리 (0) | 2022.08.03 |
[JavaScript] 백준 5430 : AC (0) | 2022.08.03 |