2학기 4주차_알고리즘( 백준2798번 : 블랙잭)

2023. 10. 28. 13:27Algorithm ( p & swlug )/Baekjoon

문제

카지노에서 제일 인기 있는 게임 블랙잭의 규칙은 상당히 쉽다. 카드의 합이 21을 넘지 않는 한도 내에서, 카드의 합을 최대한 크게 만드는 게임이다. 블랙잭은 카지노마다 다양한 규정이 있다.

한국 최고의 블랙잭 고수 김정인은 새로운 블랙잭 규칙을 만들어 상근, 창영이와 게임하려고 한다.

김정인 버전의 블랙잭에서 각 카드에는 양의 정수가 쓰여 있다. 그 다음, 딜러는 N장의 카드를 모두 숫자가 보이도록 바닥에 놓는다. 그런 후에 딜러는 숫자 M을 크게 외친다.

이제 플레이어는 제한된 시간 안에 N장의 카드 중에서 3장의 카드를 골라야 한다. 블랙잭 변형 게임이기 때문에, 플레이어가 고른 카드의 합은 M을 넘지 않으면서 M과 최대한 가깝게 만들어야 한다.

N장의 카드에 써져 있는 숫자가 주어졌을 때, M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 구해 출력하시오.

입력

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

합이 M을 넘지 않는 카드 3장을 찾을 수 있는 경우만 입력으로 주어진다.

출력

첫째 줄에 M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 출력한다.

 

📌 내풀이

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main() {

    int N;
    int S[10]; //입력받은 숫자 보관 변수
    int M;
    int result[3]; //3개 선택한 수 보관 변수
    int hap;
    int last;

    scanf("%d %d", &N ,&M);
    for (int i = 0; i < S; i++) {
        S[10] = S[i];

        while (1) {
            for (int i = 0; i < 3; i++) {
                result[3] = S[i];
                hap += S[i];
                S[0] = last;
                if (S[0] < S[1] && S[1] < M) {
                    last = S[1];
                }

                if (hap > M) 
                    i++;
                    else if (hap == M)
                    break;
                return M;

                else
                    hap == last;

                


            }
        }
    }

    printf("%d\n", last);
    return 0;
}

일단 변수를 잔뜩 선언했다.

왜냐면 계산할게 많을거같아서.. 근데 이렇게 하면 런타임에러나 컴파일 에러가 뜰거같았다.

 

일단 변수 설정해서 배열에 숫자를 N만큼 입력받고, M을 입력받는다.

그리고S로 배열을 만들어서 입력받은 숫자를 저장한다.

반복문을 통해서 3번만큼 결과값을 저장해서 합을 구하고 M보다 크면 I++ 갱신하고,

같으면 break해서 M으로 return하고 아니면 last를 return하도록했다. 

 

그런데 뭔가 부족하고 어설픈느낌이라 일단은 수정할 각오를 하고 결과를 출력해봤다.

 

 

역시나 컴파일 에러 

일단은 머릿속에 있는걸 다 표현해봤는데 정리하고 추가할 부분이 있을 것 같다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int N;
    int S[1000]; // 배열 크기 조정
    int M;
    int result[3] = {0}; // 배열 크기를 3으로 고정 및 초기화

    scanf("%d %d", &N, &M); // 

    for (int i = 0; i < N; i++) {
        scanf("%d", &S[i]);
    }

    int hap = 0;
    int last = 0;

    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            for (int k = j + 1; k < N; k++) {
                result[0] = S[i];
                result[1] = S[j];
                result[2] = S[k];

                hap = result[0] + result[1] + result[2];

                if (hap <= M && hap > last) {
                    last = hap;
                }
            }
        }
    }

    printf("%d\n", last);
    return 0;
}

 

배열을 크기를 조정해서 다시 선언하고 result 값도 배열 3으로 크기를 조정해서 초기화한다.

그리고 0에서 N 보다 작을때까지 반복하면서 , i+1 에서 N보다 작을때까지 반복하면서 j+1부터 N보다 작을때까지 반복하면서 ( 한칸씩 큰것을 표현 ) , result 값을 저장한다. 

그리고 hap을 3개의 합으로저장해서 만약에 hap이 M보다 작거나 같고  last 보다 크다면 last에 hap을 저장해서 

printf를 통해 last를 출력하도록 하였다.

 

 

( return 문은 함수를 즉시 종료시키므로, return 이후의 코드는 실행되지 않아 아까처럼 사용하면 안된다. )

 

 

맞았습니다.

 

아무래도 코드가 길거나 복잡하게 구해야할 수록 시간이 많이들거나 일부분이 부족하거나 일부분만 코드를 짤 수 있는 경우가 많은데 다양한 문제를 경험해보지 못해서인 것같다.

 

열심히 해야겠다.