문제 : https://www.acmicpc.net/problem/2003
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
문제 요약 : 부분 수열의 합이 M이 되는 경우의 수 출력
입력 | 출력 |
1 ≤ n(A) ≤ 10000 1 ≤ M ≤ 300000000 1 ≤ A[x] ≤ 30000 |
부분 수열의 합이 M이 되는 경우의 수 출력 |
JAVA
소스코드 : https://github.com/cbkpar/BOJ/blob/main/boj_2003.java
채점 번호 | 아이디 | 문제 번호 | 결과 | 메모리 | 시간 | 언어 | 코드 길이 |
31168089 | cbkpar | 2003 | 맞았습니다!! | 15164KB | 164ms | Java 11 | 761B |
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 n,m,i,s,l,r,t;
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
int[] arr = new int[n+1];
st = new StringTokenizer(br.readLine());
for(i=1;i<=n;i++) arr[i] = arr[i-1] + Integer.parseInt(st.nextToken());
s = 0;
l = 0;
r = 1;
while(true) {
if(r>n) break;
t = arr[r] - arr[l];
if(t>=m) l++;
if(t<=m) r++;
if(t==m) s++;
}
System.out.println(s);
}
}
해당 배열의 숫자가 모두 양수이므로 투포인터 방식으로 문제를 해결할 수 있다.
부분합을 미리 계산 후
l = 0, r = 1로 초기화 한 후
부분합이 원하는 값(m) 보다 크거나 같을 경우 l을 오른쪽으로 한 칸
부분합이 원하는 값(m) 보다 작거나 같을 경우 r을 오른쪽으로 한 칸
부분합이 원하는 값(m) 같을 경우 경우의 수를 1 증가시켜주며
r이 마지막 값을 본 경우에는 종료시켜준다.
- 단순하게 모든 경우의 수를 구한 코드
채점 번호 | 아이디 | 문제 번호 | 결과 | 메모리 | 시간 | 언어 | 코드 길이 |
31148547 | cbkpar | 2003 | 맞았습니다!! | 16796KB | 272ms | Java 11 | 691B |
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 n,m,i,j,s;
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
int[] arr = new int[n+1];
st = new StringTokenizer(br.readLine());
for(i=1;i<=n;i++) arr[i] = arr[i-1] + Integer.parseInt(st.nextToken());
s = 0;
for(i=0;i<n;i++) for(j=i+1;j<=n;j++) if(arr[j]-arr[i]==m) s++;
System.out.println(s);
}
}
위 방법은 배열의 값이 음수인 경우에도 적용될 수 있지만 시간복잡도가
투포인터[O(n)] 에서 모든 경우의수[O(n^2)]으로 증가하게 된다.
'백준온라인' 카테고리의 다른 글
[백준온라인] 15926번 현욱은 괄호왕이야!! (0) | 2021.08.07 |
---|---|
[백준온라인] 11444번 피보나치 수 6 (0) | 2021.08.06 |
[백준온라인] 1356번 유진수 (0) | 2021.08.04 |
[백준온라인] 2546번 경제학과 정원영 (0) | 2021.08.03 |
[백준온라인] 17404번 RGB거리 2 (0) | 2021.08.02 |