https://www.acmicpc.net/problem/2798
배열을 이용하는 문제는 항상 시행착오가 있다.
런타임 오류가 나거나 선언을 잘못하거나 값을 잘못 입력하거나 하면 코드가 완전히 다 꼬여버리더라.
이번에는 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변수로 그 배열의 길이를 구했던 부분을 완전히 덜어내 버렸다.
'C언어' 카테고리의 다른 글
while문에서 continue 사용 시 에러, 문제가 발생하는 경우 (0) | 2022.04.21 |
---|---|
[C언어] 문자열 복사 strcpy 함수 (0) | 2022.02.25 |
[C언어] char 배열 선언시 주의사항 (0) | 2022.01.24 |
[C언어] 문자 입출력 함수 getchar(), putchar() (0) | 2022.01.24 |
[C언어] 백준 1157 : 아스키 코드를 이용한 문자형 정수 변환 (0) | 2022.01.20 |