강잇
강이의 개발블로그
강잇
전체 방문자
오늘
어제
  • 분류 전체보기 (102)
    • Langauge (32)
      • Java-basic (29)
      • Java (3)
    • SpringBoot (7)
    • Algorithm (5)
      • BAEKJOON (5)
    • WEB (7)
      • HTML & CSS (7)
    • DB (1)
      • MySQL (1)
    • OS (17)
      • Mac (2)
      • Linux (4)
      • Terminal Command (11)
    • Computer Science (7)
      • Hard ware (1)
      • Database (1)
      • Data structure (2)
      • Algorithm (2)
      • Network (1)
    • Git (5)
      • 개념 (1)
      • 활용 (1)
      • Trouble Shooting (2)
    • ETC. (13)
      • Install (6)
      • IntelliJ (1)
      • Eclipse (2)
      • Error (3)
      • Tip (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 알고리즘 공부
  • CSS 박스 크기 설정
  • CSS 속성
  • 메서드
  • 자바
  • 메소드
  • 백준
  • til

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
강잇
Algorithm/BAEKJOON

[백준] 11660 구간 합 구하기 5 - Java

[백준] 11660 구간 합 구하기 5 - Java
Algorithm/BAEKJOON

[백준] 11660 구간 합 구하기 5 - Java

2022. 6. 23. 21:39

문제 

https://www.acmicpc.net/problem/11660

 

11660번: 구간 합 구하기 5

첫째 줄에 표의 크기 N과 합을 구해야 하는 횟수 M이 주어진다. (1 ≤ N ≤ 1024, 1 ≤ M ≤ 100,000) 둘째 줄부터 N개의 줄에는 표에 채워져 있는 수가 1행부터 차례대로 주어진다. 다음 M개의 줄에는 네

www.acmicpc.net

시간 제한 : 1초 (100,000,000)

표의 크기(N) : 1024

합을 구해야 하는 횟수(M) : 100,000

(x, y) : x 는 행, y는 열을 의미한다.

질의마다 문제를 풀었을 때 시간 제한에 걸리기 때문에 배열의 누적 합을 이용해 미리 배열을 만들어 놓고 문제를 푸는 방향으로 잡았다.

문제 풀이

문제에서 요구하는 정답은 (x1, y1)과 (x2, y2)가 주어졌을 때 (x1, y1), (x2, y2)에 해당하는 요소들의 합을 구해야 한다.

문제에서의 예시로 문제를 푼다면 풀이 방향은 다음과 같다.

N = 4

(x1, y1) = (2,2)

(x2, y2) = (3,4)

(1) - (1, 1)부터 (x2, y2)까지 합을 구한다.

(2) - (1, 1)부터 ((x1 - 1), y2)까지 합을 구한 뒤 (1)에서 구한 값에서 뺀다.

(3) - (1, 1)부터 (x2, (y1 - 1))까지 합을 구한 뒤 (1)에서 구한 값에서 뺀다.

(4) - (2), (3)을 진행하면서 (1, 1)에서 ((x1 - 1), (y1 - 1))까지의 값이 두 번 빼기 연산이 들어갔으므로 한 번 더해준다.

 

이대로 누적 합까지 적용해보자.

일단 배열의 누적 합을 구하는 방법은 다음과 같다.

# 해당 배열의 구간 합 구하기
sumArr[x3][y3] = arr[x3][y3] + sumArr[x3 - 1][y3] + sumArr[x3][y3 - 1] - sumArr[x3 - 1][y3 - 1]

위의 방법으로 배열을 완성하면 다음과 같다.

이제 처음 문제 풀이 방법으로 설명했던 그림을 보며 문제를 확인해보자.

표를 비교해서 보니 파란 색으로 진하게 칠 한 (4, 3)은 (1)에서 설명하는 (1, 1)에서부터 (4, 3)까지 합한 것과 같으며,

그리고 빨간 색으로 진하게 칠 한 (1, 3)와 (4, 1)은 (2)와 (3)과 같다는 것을 알 수 있다.

이 사실을 이용해 result를 구해보면 result = (4, 3) - (1, 3) - (4, 1) + (1, 1) = 42 - 6 - 10 + 1 = 27로 문제 예시에서 요구한 정답과 일치한다.

 

이것을 공식으로 나타내면 다음과 같다.

# (x1, y1) 부터 (x2, y2)까지 구간 합 구하기
result = sumArr[x2][y2] - sumArr[x1 - 1][y2] - sumArr[x2][y1 - 1] + sumArr[x1 - 1][y1 - 1]

코드

코드 1.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        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];
        int[][] sumArr = new int[n + 1][n + 1];

        // 배열에 값 채워넣기
        for (int i = 1; i <= n; i++){
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= n; j++) {
                arr[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        // 배열 누적 합 구하기
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                sumArr[i][j] = arr[i][j] + sumArr[i - 1][j] + sumArr[i][j - 1] - sumArr[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 result =
                    sumArr[x2][y2] - sumArr[x2][y1 - 1] - sumArr[x1 - 1][y2] + sumArr[x1 - 1][y1 - 1];
            System.out.println(result);
        }
        br.close();
    }
}

코드 2.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        // 배열 크기
        int n = Integer.parseInt(st.nextToken());
        // 질의
        int m = Integer.parseInt(st.nextToken());
        // 누적 합 배열
        int[][] sumArr = new int[n + 1][n + 1];
        int temp = 0;

        // 따로 배열에 저장하지 않고, 받자 마자 누적합 구하기
        for (int i = 1; i <= n; i++){
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= n; j++) {
                temp = Integer.parseInt(st.nextToken());
                sumArr[i][j] = temp + sumArr[i - 1][j] + sumArr[i][j - 1] - sumArr[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 result =
                    sumArr[x2][y2] - sumArr[x2][y1 - 1] - sumArr[x1 - 1][y2] + sumArr[x1 - 1][y1 - 1];
            System.out.println(result);
        }
        br.close();
    }
}

저작자표시 (새창열림)

'Algorithm > BAEKJOON' 카테고리의 다른 글

[백준] 10828번 : 스택 [Java - 자바]  (0) 2022.07.25
[백준] 3273 두 수의 합 - Java  (0) 2022.07.02
[백준] 2559 수열  (0) 2022.06.25
[백준] 11659 구간 합 구하기 4 - Java  (0) 2022.06.24
  • 문제 풀이
  • 코드
  • 코드 1.
  • 코드 2.
'Algorithm/BAEKJOON' 카테고리의 다른 글
  • [백준] 10828번 : 스택 [Java - 자바]
  • [백준] 3273 두 수의 합 - Java
  • [백준] 2559 수열
  • [백준] 11659 구간 합 구하기 4 - Java
강잇
강잇
학습한 내용을 정리 및 기록하는 블로그

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.