본문 바로가기
Algorithm/Baekjoon

[백준] 2798번 : 블랙잭 - Java

by unknownomad 2022. 4. 12.

https://www.acmicpc.net/problem/2798

 

2798번: 블랙잭

첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다. 합이 M을 넘지 않는 카드 3장

www.acmicpc.net



알고리즘 - 브루트 포스

정의

  • 난폭한(무식한) 힘
  • 무차별적 대입 방법

특징

  • 가능한 모든 경우의 수 대입 ➡ 조건에 만족하는 값만을 찾아냄
  • 자원만 충분하다면 원하는 값을 100% 확률로 찾을 수 있음
  • "빠짐 없이" 완전탐색 알고리즘을 잘 설계하는 게 핵심

풀이

1. Scanner

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
 
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int M = in.nextInt();
 
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = in.nextInt();
        }
        int result = search(arr, N, M);
        System.out.println(result);
    }
	
    //탐색
    static int search(int[] arr, int N, int M) {
        int result = 0;
        
        //카드 3개 뽑기 - 첫 번째 카드 : N - 2 까지 순회
        for (int i = 0; i < N - 2; i++) {
        
            //카드 2개 뽑기 - 두 번째 카드 : 첫 번째 카드 다음부터 N - 1 까지 순회
            for (int j = i + 1; j < N - 1; j++) {
            
                //카드 1개 뽑기 - 세 번째 카드 : 두 번째 카드 다음부터 N 까지 순회
                for (int k = j + 1; k < N; k++) {
                
                    //3개 카드의 합
                    int temp = arr[i] + arr[j] + arr[k];
                    
                    //M = 세 카드의 합 ➡ temp 반환 및 종료 
                    if (M == temp) {	
                        return temp;
                    }
                    //이전의 합 < 세 카드의 합 < M ➡ result 갱신
                    if(result < temp && temp < M) {
                        result = temp;
                    }
                }
            }
        }
        //모든 순회 마치면 result 반환
        return result;
    }
}

 

2. BufferedReader + StringTokenizer

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
 
public 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());
 
        int[] arr = new int[N];
        st = new StringTokenizer(br.readLine(), " ");
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        int result = search(arr, N, M);
        System.out.println(result);
    }
	
    //탐색
    static int search(int[] arr, int N, int M) {
        int result = 0;
        
        //카드 3개 뽑기 - 첫 번째 카드 : N - 2 까지 순회
        for (int i = 0; i < N - 2; i++) {
        
            //카드 2개 뽑기 - 두 번째 카드 : 첫 번째 카드 다음부터 N - 1 까지 순회
            for (int j = i + 1; j < N - 1; j++) {
            
                //카드 1개 뽑기 - 세 번째 카드 : 두 번째 카드 다음부터 N 까지 순회
                for (int k = j + 1; k < N; k++) {
                
                    //3개 카드의 합
                    int temp = arr[i] + arr[j] + arr[k];
                    
                    //M = 세 카드의 합 ➡ temp 반환 및 종료 
                    if (M == temp) {	
                        return temp;
                    }
                    //이전의 합 < 세 카드의 합 < M ➡ result 갱신
                    if(result < temp && temp < M) {
                        result = temp;
                    }
                }
            }
        }
        //모든 순회 마치면 result 반환
        return result;
    }
}

3. Scanner + 조건문

  • 첫 번째 카드가 M보다 크거나
  • 두 번째 카드까지 선택 시 두 카드의 합이 M보다 크다면
import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
 
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int M = in.nextInt();
 
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = in.nextInt();
        }
        int result = search(arr, N, M);
        System.out.println(result);
    }
	
    //탐색
    static int search(int[] arr, int N, int M) {
        int result = 0;
        
        //카드 3개 뽑기 - 첫 번째 카드 : N - 2 까지 순회
        for (int i = 0; i < N - 2; i++) {
        
            //첫 번째 카드 > M ➡ skip
            if(arr[i] > M)  {
                continue;
            }
        
            //카드 2개 뽑기 - 두 번째 카드 : 첫 번째 카드 다음부터 N - 1 까지 순회
            for (int j = i + 1; j < N - 1; j++) {
            
                //첫 번째 카드 + 두 번째 카드 > M ➡ skip
                if(arr[i] + arr[j] > M) {
                    continue;
                }
            
                //카드 1개 뽑기 - 세 번째 카드 : 두 번째 카드 다음부터 N 까지 순회
                for (int k = j + 1; k < N; k++) {
                
                    //3개 카드의 합
                    int temp = arr[i] + arr[j] + arr[k];
                    
                    //M = 세 카드의 합 ➡ temp 반환 및 종료 
                    if (M == temp) {	
                        return temp;
                    }
                    //이전의 합 < 세 카드의 합 < M ➡ result 갱신
                    if(result < temp && temp < M) {
                        result = temp;
                    }
                }
            }
        }
        //모든 순회 마치면 result 반환
        return result;
    }
}

 

 

4. BufferedReader + StringTokenizer + 조건문

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
 
public 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());
 
        int[] arr = new int[N];
        st = new StringTokenizer(br.readLine(), " ");
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        int result = search(arr, N, M);
        System.out.println(result);
    }
	
    //탐색
    static int search(int[] arr, int N, int M) {
        int result = 0;
        
        //카드 3개 뽑기 - 첫 번째 카드 : N - 2 까지 순회
        for (int i = 0; i < N - 2; i++) {
        
            //첫 번째 카드 > M ➡ skip
            if(arr[i] > M)  {
                continue;
            }
        
            //카드 2개 뽑기 - 두 번째 카드 : 첫 번째 카드 다음부터 N - 1 까지 순회
            for (int j = i + 1; j < N - 1; j++) {
            
                //첫 번째 카드 + 두 번째 카드 > M ➡ skip
                if(arr[i] + arr[j] > M) {
                    continue;
                }
            
                //카드 1개 뽑기 - 세 번째 카드 : 두 번째 카드 다음부터 N 까지 순회
                for (int k = j + 1; k < N; k++) {
                
                    //3개 카드의 합
                    int temp = arr[i] + arr[j] + arr[k];
                    
                    //M = 세 카드의 합 ➡ temp 반환 및 종료 
                    if (M == temp) {	
                        return temp;
                    }
                    //이전의 합 < 세 카드의 합 < M ➡ result 갱신
                    if(result < temp && temp < M) {
                        result = temp;
                    }
                }
            }
        }
        //모든 순회 마치면 result 반환
        return result;
    }
}

성능

  • BufferedReader > Scanner

 


출처 : https://st-lab.tistory.com/97

댓글