[백준 1806번 C/C++] 부분합
[백준 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;
}
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 16953번 C/C++] A → B (0) | 2023.11.14 |
---|---|
[백준 7576번 C/C++] 토마토 (0) | 2023.11.06 |
[백준 2470번 C/C++] 두 용액 (1) | 2023.10.30 |
[백준 3273번 C/C++] 두 수의 합 (1) | 2023.10.29 |
[백준 11054번 C/C++] 가장 긴 바이토닉 부분 수열 (0) | 2023.10.28 |
댓글
이 글 공유하기
다른 글
-
[백준 16953번 C/C++] A → B
[백준 16953번 C/C++] A → B
2023.11.14 -
[백준 7576번 C/C++] 토마토
[백준 7576번 C/C++] 토마토
2023.11.06 -
[백준 2470번 C/C++] 두 용액
[백준 2470번 C/C++] 두 용액
2023.10.30 -
[백준 3273번 C/C++] 두 수의 합
[백준 3273번 C/C++] 두 수의 합
2023.10.29