baekjoon
[백준] 1806. 부분합 (복습)
윤만석
2024. 9. 25. 03:32
문제
10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.
출력
첫째 줄에 구하고자 하는 최소의 길이를 출력한다. 만일 그러한 합을 만드는 것이 불가능하다면 0을 출력하면 된다.
골드4 부분합, 투포인터 문제입니다
#include<bits/stdc++.h>
#define FAST ios_base::sync_with_stdio(false);cin.tie(NULL)
#define mset(v) memset(v,0,sizeof(v));
#define rep(i,a) for(int i=0;i<a;++i)
#define REP(i,a) for(int i=1;i<=a;++i)
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef tuple<int, int, int>ti;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
int dy[] = { -1,0,1,0 }, dx[] = { 0,1,0,-1 }, INF = 9876543210;
int n, s, m, x, l, r, ans = INF;
int a[100001];
int main() {
FAST;
cin >> n >> m;
int sum = 0;
REP(i, n) {
//부분합에서 중요한건 첫번째 배열의 합이 0이 되어야한다는것 $$!!!
cin >> x;
sum += x;
a[i] = sum;
}
rep(l, n) {
//왼쪽 포인터는 오른쪽으로 1회 전진, 오른쪽 포인터도 1회 전진을 바꿔가면서 반복할 예정
while (a[r] - a[l] < m && r <= n)r++;
if (a[r]-a[l] >= m) {
ans = min(ans, r - l);
}
}
//갱신되지 않았으면 0을 출력
ans == INF ? cout << 0 : cout << ans;
}
매우 매우 중요한 것은, 부분합 문제에서 첫번째 배열의 값은 0이라는 것이다 !
부분합의 두 지점의 차(왼쪽 포인터와 오른쪽 포인터)는 멀어질 수록 자동으로 점 점 점 커진다.
따라서 왼쪽 포인터를 고정시켰을 때, 일단 오른쪽 포인터를 계속 이동시키다가 s보다 커지는 부분부터는 더 옮길 이유가 없다는것
따라서 그 지점부터 왼쪽 포인터를 다시 오른쪽으로 한칸옮기고, 오른쪽포인터를 다시 움직인다. 이를 반복
rep(left_pointer,n){
while(right_pointer<=n && a[right_pointer]-a[left_pointer]<s) right_pointer ++
}
만약 right_poitner가 범위 내에 있지만, 차이가 s보다 작다면 오른쪽 포인터를 오른쪽으로 한칸 옮겨준다.
복습 완 !
#include<bits/stdc++.h>
using namespace std;
int psum[100001];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
psum[0] = 0;
int n, s, x, sum = 0, ans = INT_MAX;
cin >> n >> s;
for (int i = 1; i <= n; i++) {
cin >> x;
psum[i] = sum += x;
}
int le = 0, ri = 0;
while (1) {
if (ri>n)
break;
if (psum[ri] - psum[le] >= s) {
ans = min(ans,ri - le);
le++;
}
else
ri++;
}
if (ans == INT_MAX)cout << 0;
else
cout << ans;
}
자료형 의 최대,최솟값을 저장하려면
#include <limits.h>
char num1 = CHAR_MIN; // char의 최솟값
short num2 = SHRT_MIN; // short의 최솟값
int num3 = INT_MIN; // int의 최솟값
long num4 = LONG_MIN; // long의 최솟값
long long num5 = LLONG_MIN; // long long의 최솟값
//TYPE_MAX; //자료형type의 최댓값 EX) INT_MAX