알고리즘/개념
[알고리즘개념]구간합
stubborngastropod
2023. 6. 15. 22:42
728x90
11659. 구간 합 구하기 4
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer nm = new StringTokenizer(br.readLine());
int N = Integer.parseInt(nm.nextToken());
int M = Integer.parseInt(nm.nextToken());
StringTokenizer st = new StringTokenizer(br.readLine());
int[] arr = new int[N];
int[] arr2 = new int[N];
int sum = 0;
for (int i = 0; i < N; i++) {
int n = Integer.parseInt(st.nextToken());
sum += n;
arr[i] = n;
arr2[i] = sum;
}
for (int i = 0; i < M; i++) {
StringTokenizer st2 = new StringTokenizer(br.readLine());
int l = Integer.parseInt(st2.nextToken()) - 1;
int r = Integer.parseInt(st2.nextToken()) - 1;
String res = String.valueOf(arr2[r] - arr2[l] + arr[l]);
bw.write(res + "\n");
}
bw.close();
}
}
구간 합 구하기 문제다. 배열에서 특정 구간의 요소들의 합을 구하는 건데, 배열 자체를 각 요소의 누적합으로 설정해주고 정해진 구간에 해당하는 인덱스의 값을 서로 빼주는 방식으로 풀면 된다. 난 이 과정에서 누락되는 요소를 처리해주기 위해서 배열을 두 개 사용하고 누락된 값을 추가로 더해주는 식으로 했는데, 이런 부분에서 최적화나 클린 코드에 대한 고민이 좀 더 필요하다. 다음 문제에서 이런 부분들을 보완해줬다.
11660. 구간 합 구하기 5
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[][] arr = new int[N + 1][N + 1];
for (int i = 1; i < N + 1; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j < N + 1; j++) {
arr[i][j] = arr[i - 1][j] + arr[i][j - 1] + Integer.parseInt(st.nextToken()) - arr[i - 1][j - 1];
}
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int x1 = Integer.parseInt(st.nextToken());
int y1 = Integer.parseInt(st.nextToken());
int x2 = Integer.parseInt(st.nextToken());
int y2 = Integer.parseInt(st.nextToken());
int res = arr[x2][y2] - arr[x1 - 1][y2] - arr[x2][y1 - 1] + arr[x1 - 1][y1 - 1];
bw.write(String.valueOf(res) + "\n");
}
bw.close();
}
}
2차원 배열을 이용한 구간 합 문제이다. 일단 누적합 배열을 만들 때 sum 변수를 따로 두지 않고 이전 인덱스의 값에 현재 토큰 값을 더해주는 식으로 개선했다. 이 때 방식은 x축, y축 기준으로 각각 이전 인덱스 값을 더해주고 겹치는 누적합을 빼준 다음 현재 토큰의 값을 더해준다. 2차원 배열의 크기를 주어진 길이보다 1씩 크게 만들어서 위쪽, 왼쪽에 빈 요소를 두는 것이 포인트다.
그리고 주어진 x1, y1, x2, y2 값에 대해
(x2, y2까지의 누적합) - (x1 - 1 행까지의 누적합) - (y1 - 1 열까지의 누적합) + (x1 - 1, y1 - 1까지의 누적합)
을 계산해서 결과로 출력한다.
알고보니 이전에 파이썬으로 실패했던 문제였다. 당시 구간합 개념을 몰라서 못풀었는데, 역시 개념이 탄탄해야 뭐든 풀 수 있는가보다. B형 치기 전에 열심히 공부해봐야겠다.
728x90