https://www.acmicpc.net/problem/2015
2015번: 수들의 합 4
첫째 줄에 정수 N과 K가 주어진다. (1 ≤ N ≤ 200,000, |K| ≤ 2,000,000,000) N과 K 사이에는 빈칸이 하나 있다. 둘째 줄에는 배열 A를 이루는 N개의 정수가 빈 칸을 사이에 두고 A[1], A[2], ..., A[N]의 순서로
www.acmicpc.net
#include <iostream>
#include <map>
#define fastio() ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
long long n, k, cnt, lis[202020], acc[202020];
map<long long, long long> m;
int main() {
fastio();
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> lis[i];
for (int i = 1; i <= n; i++) acc[i] = acc[i - 1] + lis[i];
for (int i = 1; i <= n; i++) {
if (acc[i] == k) cnt++;
if (m.find(acc[i] - k) != m.end()) cnt += m[acc[i] - k];
if (m.find(acc[i]) != m.end()) m[acc[i]]++;
else m.insert({acc[i], 1});
}
cout << cnt;
return 0;
}
|
cs |
걸린 시간 : 00:24:36
풀이
1. 누적 합을 구한다.
2. 누적 합을 사용하여 부분 합을 구한다.
#include <iostream>
#define fastio() ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
int n, k, cnt, lis[202020], acc[202020];
int main() {
fastio();
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> lis[i];
for (int i = 1; i <= n; i++) acc[i] = acc[i - 1] + lis[i];
for (int i = 0; i <= n; i++) for (int j = i + 1; j <= n; j++) if (acc[j] - acc[i] == k) cnt++;
cout << cnt;
return 0;
}
|
cs |
O(n^2)로 시간초과가 납니다.
2. map을 사용한다.
앞에 누적 합이 얼마이며, 몇 개나 있는 지를 map으로 저장하면, 최종 O(nlogn)이 됩니다.
'백준(C, C++) > 골드' 카테고리의 다른 글
백준 23832: 서로소 그래프 (0) | 2022.07.09 |
---|---|
백준 12904: A와 B [C/C++] (0) | 2022.06.27 |
백준 1405: 미친 로봇 [C/C++] (0) | 2022.06.16 |
백준 1744: 수 묶기 [C/C++], 다이나믹 프로그래밍 (0) | 2022.06.15 |
백준 2668: 숫자 고르기 [C언어], 정보올림피아드 (0) | 2022.06.15 |