2003. 수들의 합2 (S4)
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
0.5 초 | 128 MB | 60696 | 29353 | 20176 | 48.367 % |
문제
N개의 수로 된 수열 A[1], A[2], …, A[N] 이 있다. 이 수열의 i번째 수부터 j번째 수까지의 합 A[i] + A[i+1] + … + A[j-1] + A[j]가 M이 되는 경우의 수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N(1 ≤ N ≤ 10,000), M(1 ≤ M ≤ 300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.
출력
첫째 줄에 경우의 수를 출력한다.
summary
수열의 부분 합이 M인 경우의 수
- 정렬 X
strategy
투포인터(모든 경우의 수를 찾는건 시간초과)
- 합이 작으면 끝포인터를 이동 (endIdx)
- 합이 크면 시작포인터를 이동 (startIdx)
- 시작 포인터와 끝포인터가 배열 인덱스를 벗어나지 않게 주의
note
- 1 ≤ N ≤ 10,000
- 1 ≤ M ≤ 300,000,000
- A[x]는 30,000을 넘지 않는 자연수
import java.util.*;
import java.io.*;
public class Main {
static int N, M;
static String[] board;
static int answer = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
board = br.readLine().split(" ");
int startIdx = 0;
int endIdx = 0;
int sum = Integer.parseInt(board[endIdx]);
while(startIdx < N) {
if(sum == M) {
answer++;
sum -= Integer.parseInt(board[startIdx++]);
} else if(sum < M) {
if(endIdx == N - 1) break; // endIdx 가 더 이상 이동할 수 없으면 종료
sum += Integer.parseInt(board[++endIdx]);
} else {
sum -= Integer.parseInt(board[startIdx++]);
}
}
System.out.println(answer);
}
}
문제 | 결과 | 메모리 | 시간 | 언어코드 | 길이 |
2003 | 맞았습니다!! | 15696 KB | 124 ms | Java 11 / 수정 | 1073 B |
memo
- 인덱스 범위 안벗어나게 하는 게 은근 복잡
'문제 풀이 > 백준' 카테고리의 다른 글
[JAVA 35] 1316. 그룹 단어 체커 (0) | 2024.09.23 |
---|---|
[JAVA 32] 20040. 사이클 게임 (1) | 2024.09.22 |
[JAVA 30] 2608. 로마숫자 (0) | 2024.09.20 |
[JAVA 29] 1002. 터렛 (0) | 2024.09.14 |
[JAVA 28] 11057. 오르막 수 (1) | 2024.09.13 |