白駿2015号:獣の和4-SWIFT


https://www.acmicpc.net/problem/2015
難易度-金貨5🥇
アルゴリズム分類:累積
🧐 質問へのアクセス
部分和を求めるたびに、もちろんタイムアウトします.
だから累積和を求めた後、二重砲口で答えを求めてみたが、これもタイムアウトした.
for i in 0..<n {
	for j in 0..<i {
    	if pSum[i] - pSum[j] == k {
        	ans += 1
        }
    }
}
時間の複雑さを別の方法でO(N)に変更せざるを得ない.
だから一度だけforゲートを回る方法はないかと考えました.
for i in 0..<n {
	//현재 누적합이 주어졌을때, index ~ i의 누적합이 k가 되는 구간을 찾는 방법??
	//pSum[i]가 x일때, pSum[index] = x-k 인 index를 찾아야함
}
蓄積してディックシーケンスに保存する場合、pSum[index]=x-kはdict[x-k]の部分を見つけることができる.

完全なコード
//2015번 수들의 합 4

let t = readLine()!.split(separator: " ").map{Int(String($0))!}
let (n,k) = (t[0],t[1])
let arr = readLine()!.split(separator: " ").map{Int(String($0))!}

var ans = 0
var pSum = 0    //누적합을 저장할 변수
var sumDict = [Int:Int]()   //key = 누적합 : value = 개수

for i in 0..<n {
    //누적합 계산하기
    pSum += arr[i]
    
    //0~i까지의 누적합이 k라면 + 1
    if pSum == k {
        ans += 1
    }
    
    // pSum - k, pSum 일 경우 ans에 그 값만큼 추가 (pSum - (pSum-k) = k 이므로..)
    if let value = sumDict[pSum - k] {
        ans += value
    }
    
    // sumDict에서 key가 pSum인 값을 += 1
    if let value = sumDict[pSum] {
        sumDict[pSum] = value + 1
    } else {
        sumDict[pSum] = 1
    }
}

print(ans)
一行の評価:金色5より難しいようです.