일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- StateObject
- 숭실대
- 소프트웨어분석및설계
- 애플 디벨로퍼 아카데미
- OS
- ObservableObject
- apple developer academy 후기
- 애플 디벨로퍼 아카데미 21주차 회고
- SWIFT
- 네이버 치지직
- 데이터베이스
- 네이버 부스트캠프
- sqoop
- 애플 디벨로퍼 아카데미 후기
- 치지직
- 애플 아카데미 후기
- Apple Developer Academy @ POSTECH
- swift문법
- 운영체제
- 데이터베이스 공부
- Swift 기능
- iOS 개발 오류
- global soop
- 제앱소
- 앱 비교 프로젝트
- Swift 디자인패턴
- Swift 문법
- react
- useReducer
- ObservedObject
- Today
- Total
사과하는 제라스
[백준 BOJ 2798번] 블랙잭 본문
목차
출처 : https://www.acmicpc.net/problem/2798
1. 문제
카지노에서 제일 인기 있는 게임 블랙잭의 규칙은 상당히 쉽다. 카드의 합이 21을 넘지 않는 한도 내에서, 카드의 합을 최대한 크게 만드는 게임이다. 블랙잭은 카지노마다 다양한 규정이 있다.
한국 최고의 블랙잭 고수 김정인은 새로운 블랙잭 규칙을 만들어 상근, 창영이와 게임하려고 한다.
김정인 버전의 블랙잭에서 각 카드에는 양의 정수가 쓰여 있다. 그 다음, 딜러는 N장의 카드를 모두 숫자가 보이도록 바닥에 놓는다. 그런 후에 딜러는 숫자 M을 크게 외친다.
이제 플레이어는 제한된 시간 안에 N장의 카드 중에서 3장의 카드를 골라야 한다. 블랙잭 변형 게임이기 때문에, 플레이어가 고른 카드의 합은 M을 넘지 않으면서 M과 최대한 가깝게 만들어야 한다.
N장의 카드에 써져 있는 숫자가 주어졌을 때, M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 구해 출력하시오.
2. 입력
첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다.
합이 M을 넘지 않는 카드 3장을 찾을 수 있는 경우만 입력으로 주어진다.
5 21
5 6 7 8 9
10 500
93 181 245 214 315 36 185 138 216 295
3. 출력
첫째 줄에 M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 출력한다.
21
497
4. 풀이
문제의 핵심은 브루트 포스이다.
브루트 포스란?
브루트 포스 알고리즘은 간단히 말하자면 전체 조사이다. 모든 경우의 수들을 중복없이 다 조사해보는 것이다.
이 문제에서는 N장의 카드에 쓰여진 숫자들 중 3개를 뽑는 조합(nC3)을 브루트 포스 알고리즘을 이용하여 모두 구한 후 그 중 가장 M과 가까운 숫자를 출력하면 된다.
이때, 3중 for문을 활용하여 풀텐데 첫번째로 오는 카드는 1번째부터 N-2번째까지(첫번째에 N-1이나 N번째 카드가 오면 3개를 선택할 수 없음), 두번째에는 첫번째 이후 카드부터 N-1번째까지, 세번째에는 두번째 이후 카드부터 N번째까지 선택할 수 있는 폭을 두어 풀면 된다.
제일 먼저 Max값을 MIN_VALUE를 활용하여 극한의 최소값을 넣어두고 각 케이스마다 Max값과 비교하여 Max초과 M이하인 경우엔 Max값을 그 케이스의 3개 카드의 합으로 변경한다.
5. 소스코드
import java.io.*;
import java.util.*;
class Main{
public static void main(String [] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
int [] nums = new int [N];
for(int i=0; i<N; i++) nums[i] = Integer.parseInt(st.nextToken());
int Max = Integer.MIN_VALUE;
for(int i=0; i<N-2; i++){
for(int j=i+1; j<N-1; j++){
for(int k=j+1; k<N; k++){
if(Max < nums[i]+nums[j]+nums[k] && nums[i]+nums[j]+nums[k] <= M){
Max = nums[i]+nums[j]+nums[k];
}
}
}
}
System.out.println(Max);
}
}
6. 배운 것
브루트 포스 알고리즘에 대한 정의와 이를 사용하는 경우에 대해 공부해보고 이를 3중 for문을 통해 무작정 진행해보았다. 앞으로 풀어볼 브루트 포스 알고리즘 문제들 중에서 n중 for문 외에 적용할 수 있는 방법이 달리 있을지 더 공부해보아야겠다.
'JAVA 백준 알고리즘 문제풀이 > 브루트 포스' 카테고리의 다른 글
[백준 BOJ 1436번] 영화감독 숌 (0) | 2021.10.20 |
---|