배열을 이용하는 문제는 항상 시행착오가 있다.
런타임 오류가 나거나 선언을 잘못하거나 값을 잘못 입력하거나 하면 코드가 완전히 다 꼬여버리더라.
이번에는 3가지의 카드를 어떻게 뽑아야 하는지부터 난관이었다.
카드를 뽑는 것이기 때문에 중복은 없어야했고, 모든 경우의 수를 굳이 다 반복문으로 돌려볼 필요는 없다고 생각했다.
(첫번째 시도)
#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변수로 그 배열의 길이를 구했던 부분을 완전히 덜어내 버렸다.
배열을 쓰지 않고도 풀 수 있는 부분이 있는지 한번 더 확인해보자.
그리고 같은 조건으로 반복문을 두 번 돌릴 일이 있다면 더 간단하게 축약할 수 있는
방법이 분명히 있을 것이다.