[C언어] 백준 2798 : 블랙잭

728x90

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

 

2798번: 블랙잭

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

www.acmicpc.net


배열을 이용하는 문제는 항상 시행착오가 있다.
런타임 오류가 나거나 선언을 잘못하거나 값을 잘못 입력하거나 하면 코드가 완전히 다 꼬여버리더라.

이번에는 3가지의 카드를 어떻게 뽑아야 하는지부터 난관이었다.
카드를 뽑는 것이기 때문에 중복은 없어야 했고, 모든 경우의 수를 굳이 다 반복문으로 돌려볼 필요는 없다고 생각했다.

 

1차 시도

#include <stdio.h>
int main(void){
    int num=3, jack=10, i,j,k, narr[500],count=0,max=0;
    scanf("%d %d",&num,&jack);
    int arr[num];
    for(i=0; i<num; i++){
        scanf("%d",&arr[i]);
    }
    for(i=0; i<num; i++){
        for(j=1; j<num; j++){
            for(k=2; k<num; k++){
                if(i!=j && i!=k && j!=k && arr[i]+arr[j]+arr[k]<=jack){
                    narr[count]=arr[i]+arr[j]+arr[k];
                    count++;
                }
            }
        }
    }
    for(i=0; i<count; i++){
        if(max<narr[i]){max=narr[i];}
    }
    printf("%d",max);
    return 0;
}

제출 시 런타임 오류가 떠서 틀렸던 코드다. narr 배열은 3개의 카드를 뽑았을 때, 카드의 값이 전부 다르고 합이 jack의 값보다 작거나 같은 경우를 담는 역할을 했다.


근데 그 크기를 얼마나 정해야 할지 몰랐고, 만약에 num에다가 10이상의 큰 수로 입력을 받아버리면 narr가 담아야 하는 용량이 제한을 벗어나기 때문에 문제가 있는 코드였다.

따라서 배열에 굳이 담을 필요없이 반복문에 담긴 조건문에서 필요한 경우의 수를 거를 수 있는 방법을 찾아야 했다.또한 for문 3개를 써서 경우의 수를 돌리는 과정에서도 문제가 발생했다.
의도와 달리 카드를 중복해서 뽑는 경우의 수를 걸러내지 못했다.

 

완성된 코드

#include <stdio.h>
int main(void){
    int num=3, jack=10, i,j,k,sum=0,max=0;
    scanf("%d %d",&num,&jack);
    int arr[num];
    for(i=0; i<num; i++){
        scanf("%d",&arr[i]);
    }
    for(i=0; i<num; i++){
        for(j=i+1; j<num; j++){
            for(k=j+1; k<num; k++){
                    sum=arr[i]+arr[j]+arr[k];
                    if(sum<=jack && max<sum){max=sum;}
            }
            
        }
    }
    printf("%d",max);
    return 0;
}

삼중 반복문의 조건을 중복된 경우의 수가 일어나지 않도록 수정했다.

반복문의 모든 값을 배열에 넣는 것을 포기하고, 모든 경우의 수마다 1차적으로 sum에 세 수의 합을 저장한다.

그리고 즉시 조건에 맞는지 확인하고, 기존의 max값 보다 크면 새로운 max값으로 갱신할 수 있도록 한다.

첫번째 코드에서 narr배열로 필요한 값을 재배치하고 count변수로 그 배열의 길이를 구했던 부분을 완전히 덜어내 버렸다.

728x90