⭐ 코딩테스트/백준
[백준 1806번 C/C++] 부분합
Designerd
2023. 10. 31. 10:48
[백준 1806번 C/C++] 부분합
https://www.acmicpc.net/problem/1806
1806번: 부분합
첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.
www.acmicpc.net
해결방안
투 포인터
누적합
처음 시도한 코드 - 시간초과
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n, s; // n: 수열의 길이, s: 수열의 부분합 최소값
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> s;
vector<int> v(n);
for(int i=0; i<n; i++){
cin >> v[i];
}
vector<int> result;
int left = 0;
int right = 1;
int sumNum = v[left];
while (left < n - 1)
{
if (right > n - 1) break;
if (sumNum < s){
sumNum += v[right];
right++;
}
else if (sumNum >= s){
result.push_back(right-left);
sumNum = 0;
left++;
if (v[left] >= s)
{
result.push_back(1);
cout << "1\n";
return 0;
}
sumNum += v[left];
right = left + 1;
}
}
if (result.size() == 0)
cout << "0\n";
else{
sort(result.begin(), result.end());
cout << result[0] << "\n";
}
return 0;
}
정답 코드 - 누적합 Ver.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n, s; // n: 수열의 길이, s: 수열의 부분합 최소값
vector<int> result;
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> s;
vector<int> v(n);
int front = 0;
int sumNum = 0;
for(int i=0; i<n; i++){
cin >> v[i];
sumNum += v[i];
while (sumNum >= s)
{
result.push_back(i - front + 1);
sumNum -= v[front];
front++;
}
}
if (result.size() == 0)
cout << "0\n";
else {
sort(result.begin(), result.end());
cout << result[0] << "\n";
}
return 0;
}
입력과 동시에 누적합이 시행되도록 코드를 수정하였다.
다른 풀이 - 투 포인터 Ver.
#include <iostream>
#include <vector>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
int n, s;
int main()
{
cin >> n >> s;
vector<int> v(n);
for (int i = 0; i < n; i++)
cin >> v[i];
int left = 0, right = 0;
int sumNum = 0, minLen = INT_MAX;
while (left <= right)
{
if (sumNum >= s)
{
minLen = min(minLen, right - left); // 가장 짧은 길이로 업데이트
sumNum -= v[left];
left++;
}
else if (right == n)
break;
else {
sumNum += v[right];
right++;
}
}
if (minLen == INT_MAX)
cout << 0 << "\n";
else
cout << minLen << "\n";
return 0;
}