1. 문제
16287번: Parcel
입력은 표준입력을 사용한다. 입력의 첫 줄에는 무게 w(10 ≤ w ≤ 799,994)와 A의 원소 개수 n(4 ≤ n ≤ 5,000)이 공백으로 분리되어 주어진다. 다음 줄에는 A의 원소인 n개의 정수 ai ∈ A(1 ≤ i ≤ n)가
www.acmicpc.net
2. 접근방법
5000개의 N 중에 4개를 뽑아서 합할때 W에 정확히 맞추는 4개의 숫자가 있는지 찾는 문제
간단히 조합으로 해결하려 하면 5000 C 4 무조건 시간초과가 터지니 다른 방법을 찾아야 한다.
해결방법은
A + B + C + D = W 에서
A + B = W - C - D 형태로 바꾸어 생각하는 것이다.
2중 for문으로
A+B의 값을 계산하고 이에 해당하는 C D값이 있다면 YES출력
없다면
C = A
0 <= D < A
로 생각해고 W - C -D 값을 기록하고 다음 A값으로 넘어간다.
이러면 N C 2 + N(N+1)/2
시간복잡도는 O(N^2) 이 되어 해결이 가능하다.
3. 자바 코드
package Gold;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class G1_16287Parcel {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int W = Integer.parseInt(st.nextToken());
int N = Integer.parseInt(st.nextToken());
int arr[] = new int[N];
boolean sum[] = new boolean[400001];
st = new StringTokenizer(br.readLine());
for(int i = 0 ; i < N ; i++)
arr[i] = Integer.parseInt(st.nextToken());
boolean ok = false;
gg:for(int i = 0 ; i < N ; i++) {
for(int j = i+1 ; j < N ; j++) {
int now = arr[i] + arr[j];
if(now >= W || W- now > 400000 )
continue;
if(sum[W-now]) {
ok = true;
break gg;
}
}
for(int j = 0 ; j < i ; j++)
sum[arr[i]+arr[j]] = true;
}
System.out.println(ok?"YES":"NO");
}
}
4. 마치며
4개를 뽑아야만 한다는 생각에 빠져서 2개 2개로 나누는 것을 생각해내기가 어려웠던 문제
신선했다.
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[백준] 1034 램프 (0) | 2020.12.18 |
---|---|
[백준] 2457 공주님의 정원 (0) | 2020.12.17 |
[백준] 20303 할로윈의 양아치 (0) | 2020.12.10 |
[백준] 20209 스트레이트 스위치 게임 (부분집합) (0) | 2020.12.05 |
[백준] 20209 스트레이트 스위치 게임(BFS) (0) | 2020.12.03 |