🔒 문제
2003번: 수들의 합 2
첫째 줄에 N(1 ≤ N ≤ 10,000), M(1 ≤ M ≤ 300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.
www.acmicpc.net
🔑 알고리즘
투 포인터
💡 풀이
투 포인터를 이용하여 O(N)의 시간 복잡도로 해결할 수 있다.
범위의 시작을 의미하는 포인터 S와 끝을 의미하는 포인터 E를 모두 배열의 맨 앞에 두고
두 포인터 사이의 배열 값의 합이
M보다 작다면 값을 늘려야하므로 E를 오른쪽으로 한 칸 움직이고,
M보다 크다면 값을 줄여야하므로 S를 오른쪽으로 한 칸 움직이고,
M과 같다면 count를 1 증가시키고 S를 오른쪽으로 한 칸 움직인다.(E도 무관)
M이 배열의 끝에 닿을 때까지 이 과정을 반복한다.
이때 두 포인터가 한 번에 한칸씩만 움직이면서
E가 움직이면 새로운 값을 더해주고 S가 움직이면 기존의 값을 빼주면 된다.
✏️ 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int s = 0;
int e = 0;
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[] arr = new int[n + 1];
st = new StringTokenizer(br.readLine(), " ");
for (int i = 0; i < n; i++)
arr[i] = Integer.parseInt(st.nextToken());
int sum = arr[0];
int count = 0;
if(sum == m) count++;
while (true) {
if (sum < m) sum += arr[++e];
else if (sum >= m) sum -= arr[s++];
if (e == n) break;
if(sum == m) count++;
}
System.out.println(count);
}
}
'Algorithm > 백준(BOJ)' 카테고리의 다른 글
[백준] 2302. 극장 좌석 (Java) (0) | 2022.09.18 |
---|---|
[백준] 2637. 장난감 조립 (Java) (1) | 2022.09.16 |
[백준] 1822. 차집합 (Java) (0) | 2022.09.13 |
[백준] 2252. 줄 세우기 (Java) (0) | 2022.09.13 |
[백준] 14267. 회사 문화 1 (Java) (0) | 2022.09.13 |