문제

수 N개가 주어졌을 때, i번째 수부터 j번째 수까지 합을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 수의 개수 N과 합을 구해야 하는 횟수 M이 주어진다. 둘째 줄에는 N개의 수가 주어진다. 수는 1,000보다 작거나 같은 자연수이다. 셋째 줄부터 M개의 줄에는 합을 구해야 하는 구간 i와 j가 주어진다.

출력

총 M개의 줄에 입력으로 주어진 i번째 수부터 j번째 수까지 합을 출력한다.

내가 푼 풀이

접근방법: 세그먼트 트리 구조

세그먼트 트리를 구현하여 구간합을 출력한다.

<세그먼트 트리>

https://jenikeju.tistory.com/290

 

세그먼트 트리 Swift

세그먼트 트리세그먼트 트리는 트리형태의 자료구조로 해당 노드에는 구간합이 저장되어 있다.일반적으로 배열에서 특정 구간의 합을 구해야 한다면 O(N)이 걸린다.세그먼트 트리는 노드마다

jenikeju.tistory.com

 

import Foundation

// 입력받기
let input = readLine()!.split(separator: " ").map{Int(String($0))!}
let N = input[0], M = input[1]
var arr = readLine()!.split(separator: " ").map{Int(String($0))!}
arr.insert(0, at: 0)
var tree = Array(repeating: 0, count: arr.count*4)

// 세그먼트 트리 생성함수
func sgInit(_ start: Int,_ end: Int,_ index: Int) -> Int {
    if start == end {
        tree[index] = arr[start]
        return tree[index]
    }
    let mid = (start+end)/2
    tree[index] = sgInit(start, mid, index*2) + sgInit(mid+1, end, index*2+1)
    return tree[index]
}
// 세그먼트 트리생성
sgInit(1, arr.count-1, 1)

// 세그먼트 트리의 구간합 구하기
func sgSum(_ start: Int,_ end: Int,_ index: Int,_ left: Int,_ right: Int) -> Int {
    if left > end || right < start { return 0 }
    if start >= left && end <= right { return tree[index] }
    let mid = (start+end)/2
    
    return sgSum(start, mid, index*2, left, right) + sgSum(mid+1, end, index*2+1, left, right)
}

// 구간합 출력
for i in 0..<M {
    let range = readLine()!.split(separator: " ").map{Int(String($0))!}
    print(sgSum(1, arr.count-1, 1, range[0], range[1]))
}

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-1992 쿼드트리 Swift  (0) 2024.05.03
BOJ-10986 나머지 합 Swift  (1) 2024.05.02
14725-개미굴 Swift  (0) 2024.04.30
BOJ-1043 거짓말 Swift  (0) 2024.04.29
BOJ-1976 여행 가자 Swift  (0) 2024.04.29

+ Recent posts