티스토리 뷰
백준 온라인 저지(BOJ) 1806번 부분합
https://www.acmicpc.net/problem/1806
1806번: 부분합
첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.
www.acmicpc.net
* 사용언어 : C언어, C++
1. 문제
N개 자연수 수열에서 연속된 수들의 부분합이 S 이상이 되는 것 중 가장 짧은 길이 출력
2. 풀이
투 포인터 개념을 이해하시면 풀 수 있는 문제입니다.
문제의 목적이 S 이상이 되는 가장 짧은 길이를 찾는 문제이므로,
low, high 라는 2개의 포인터로 부분합의 시작과 끝을 아래 조건에 따라 하나씩 늘려가면서 길이를 찾으면 됩니다.
조건 1) 현재 부분합(low~high sum)이 S 보다 작은 경우
- high 를 오른쪽으로 한 칸 이동하고 sum 에 arr[high] 값을 더해준다.
조건 2) 현재 부분합(low~high sum)이 S 보다 크거나 같은 경우
- 현재 len 값과 현재 부분합의 길이(high - low + 1)를 비교하여 작은 값을 len 에 기록한다.
- 다음 탐색을 위해 sum 에서 arr[low] 값을 빼주고 low 를 오른쪽으로 한 칸 이동한다.
while 문은 아래 2가지 조건을 만족하는 동안 반복합니다.
반복 1) low 가 high 보다 작거나 같은 경우
- 수열 중 1개의 숫자만으로 S 이상이 되면, 다음 반복 시 low 가 high 보다 커지게 됩니다.
- low 가 더 커진 경우 최소 길이는 1이고 더 이상 탐색할 이유가 없으므로 반복하지 않습니다.
반복 2) high 가 N 보다 작은 경우
- high 가 N 에 도달했다는 것은 현재 sum 이 S 보다 작은 상태로 끝까지 도달한 것 입니다.
- sum 을 더 크게 만들 수 있는 방법이 없으므로 더 이상 반복하지 않습니다.
3. 코드
#include <stdio.h>
#define MAX_ARR 100000
#define min(x,y) x < y ? x : y
int main() {
int n, s;
int arr[MAX_ARR];
scanf("%d %d", &n, &s);
for (int i = 0; i < n; ++i) {
scanf("%d ", &arr[i]);
}
int low = 0;
int high = 0;
int sum = arr[0];
int len = n + 1;
while (low <= high && high < n) {
if (sum < s) {
sum += arr[++high];
}
else {
len = min(len, high - low + 1);
sum -= arr[low++];
}
}
if (len == n + 1) len = 0;
printf("%d\n", len);
return 0;
}
'개발자 > 문제풀이 (C언어)' 카테고리의 다른 글
[백준/BOJ] 2588번 곱셈 (C/C++) (0) | 2021.04.16 |
---|---|
[백준/BOJ] 1912번 연속합 (C/C++) (0) | 2021.03.29 |
[백준/BOJ] 11729번 하노이 탑 이동 순서 (C/C++) (0) | 2021.03.21 |
[백준/BOJ] 10171번 고양이 (C/C++) (1) | 2020.12.27 |
[백준/BOJ] 10871번 X보다 작은 수 (C/C++) (0) | 2019.03.23 |
- Total
- Today
- Yesterday
- 최재천의공부
- JUNGOL
- 시대예보
- 나의첫죽음학수업
- 삼성전자
- 여가포인트
- 동탄에듀센터
- 인간본성불패의법칙
- 자료구조
- 당신도느리게나이들수있습니다
- 나는늘잘해야한다고생각한다
- 긴 자리 덧셈 뺄셈
- 정올
- 자동차보험
- 안전운전특약
- 동탄에듀센터2
- 유연함의힘
- 독서 감상평
- 정세현의통찰
- 센터독서클럽
- 관계가상처가되기전에
- 알고리즘
- AdSendse
- 쿠프마케팅
- 문현공
- 영화감상평
- 독서감상평
- 긴 자리 곱셈
- 세상을 읽는 새로운 언어 빅데이터
- 호암의마지막꿈
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |