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

2023. 1. 27. 06:43·알고리즘/알고리즘 유형
반응형

2차원 배열 구간 합

일단 1차원 배열의 구간 합부터 이해해야한다.

 

[백준] 11659_구간 합 구하기4 - JAVA

구간 합 구간 합은 배열을 이용하여 시간 복잡도를 더 줄이기 위해 사용하는 알고리즘이다. 구간 합을 이용하려면 합 배열을 구해야 한다. 합 배열 만들기 S[i] = S[i-1] + A[i] 인덱스 0 1 2 3 A 10 10 10 1

devhan.tistory.com

 

2차원 배열의 구간 합은 어려운 거 같으면서도 이해하면 쉽다. 일단 문제의 예시로 설명해보자. 

위 원본 배열을 A라 하자. 원본 배열의 크기가 +1 된 이유는 구간 합 배열의 크기와 똑같이 만들어주기 위함이다. 이 A의 합 배열(S)을 채워보자. 

배경색이 있는 곳이 시작점이다.

for문의 시작 인덱스는 0이 아닌 1이다. index 계산 시 0부터 시작이면 0-1이 되어버리기 때문이다. 아무튼 제일 첫 번째 값을 넣는 건 굳이 계산하지 않아도 '1'이 들어갈 것이라고 유추할 수 있다.

그 다음 배열 자리엔 S[1,1]의 값인 1과 A[1,1]의 값인 2를 더한 값이 들어가야한다. 이런식으로 테두리를 채워보면 아래와 같다.

그럼 이제 어려워 보이는 저 부분에 들어갈 값을 구해보자. 헷갈릴까봐 잘라왔다.

저 주황색 칸 기준으로 왼쪽 칸의 값 + 윗쪽 칸의 값 - 중복된 대각선 칸의 값 + 원본 주황색 칸의 값으로 안에 들어갈 값을 계산할 수 있다. 중복된 대각선이란 주황색 칸 왼쪽, 윗쪽 칸은 구간 합 계산이 되어있는 값이기 때문에 1이 총 두 번 계산되어 중복되었다고 표현했다... 좀 더 프로그래밍적으로 정리해보자면...

구간 합 배열 채우는 공식

S[i][j] = S[i-1][j] + S[i][j-1] - S[i-1][j-1] + A[i][j]

위 공식으로 구간 합 배열을 채우면 아래와 같이 완성된다.

구간 합 배열 S

구간 합 배열을 완성했으니 이제 그 다음 단계로 나아가야한다. 그 다음 단계는 4개의 숫자를 입력받아 해당 범위의 구간 합을 구하는 일이다. 예제와 똑같이 '2 2 3 4'를 받았다고 치자.

저 범위의 구간 합을 구하면 된다. 이 방법도 구간 합 배열을 채울때와 비슷하다. 일단 S[1,1]부터 S[3,4]의 구간합은 42이다. 그리고 우리가 구하고자 하는 범위는 위와 같다. 그림으로 보자면 아래와 같다.

두 범위가 겹치지 않는 S[1,4], S[3,1]의 구간합을 S[3,4] 구간합에 빼주면 된다.

다만 S[1,1]은 S[1,4]와 S[3,1] 구간 합 계산에 모두 쓰였으므로 계산이 중복되었다. 구간 합을 채울 때와는 다르게 중복된 값을 두 번 소실했으니 한 번 채워줘야한다. 그래서 결론은 42 - 10 - 6 + 1 = 27이 된다. 이것 또한 프로그래밍적으로 나타내보자면...

구간 합을 구하는 공식

result = S[X2][Y2] - S[X1-1][Y2] - S[X2][Y1-1] +S[X1-1][Y1-1]

 

백준_11660

 

11660번: 구간 합 구하기 5

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

www.acmicpc.net

 

코드

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 size = Integer.parseInt(st.nextToken());
        int qCnt = Integer.parseInt(st.nextToken());

        int arr[][] = new int[size+1][size+1];

        for(int i = 1; i <= size; i++) {
            st = new StringTokenizer(br.readLine());
            for(int j = 1; j <= size; j++) {
                arr[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int sumArr[][] = new int[size+1][size+1];
        for(int i = 1; i <= size; i++) {
            for(int j = 1; j <= size; j++) {
                sumArr[i][j] = sumArr[i][j-1] + sumArr[i-1][j] - sumArr[i-1][j-1] + arr[i][j];
            }
        }

        for(int i = 0; i < qCnt; 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[x1-1][y2] - sumArr[x2][y1-1] + sumArr[x1-1][y1-1];
            System.out.println(result);
        }
    }
}

 

제출 결과

 

이번 문제는 구현보다.. 문제 자체를 이해하는 게 더 어려웠던 거 같다..수포자의 설움

반응형
저작자표시 비영리 변경금지 (새창열림)
'알고리즘/알고리즘 유형' 카테고리의 다른 글
  • [백준] 1940_주몽 - JAVA
  • [백준] 2018_수들의 합5 - JAVA
  • [백준] 10986_나머지 합 - JAVA
  • [백준] 11659_구간 합 구하기4 - JAVA
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스프링부트
    전자정부프레임워크
    Java
    프로그래머스
    에러해결
    인프런
    코딩테스트
    RESTful
    토이프로젝트
    Spring
    react
    기출문제
    IT
    백준
    프론트엔드
    개발자
    springboot
    SQL
    토비의스프링부트
    MSA
    JPA
    자바스크립트
    egov
    oracle
    알고리즘
    QueryDSL
    운영체제
    넥사크로
    SpringBoot를 이용한 RESTful Web Service 개발
    방통대
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
[백준] 11660_구간 합 구하기5 - JAVA
상단으로

티스토리툴바