<문제>https://www.acmicpc.net/problem/3052
<정답 코드>
#include<stdio.h>
int main(void)
{
int arr[10];
for (int i = 0; i < 10; i++) {
scanf("%d", &arr[i]);
}
int res, k = 0;
int num[42] = { 0 };
for (int j = 0; j < 10; j++) {
res = arr[j] % 42;
num[res] += 1;
}
for (int g = 0; g < 42; g++) {
if (num[g] >= 1) {
k++;
}
}
printf("%d", k);
return 0;
}
<풀었던 과정>
10개의 수를 입력을 받아 42로 나눈 나머지를 가지고 서로 다른 값이 몇 개인지 개수를 구하는 문제이다.
처음에는 42로 나눈 나머지를 0~9까지로만 생각하고 int num [10]으로 선언해 주었었다. 그런데 코드의 반례가 있는지 생각하는 과정에서 42로 39를 나누면 나머지는 39라는 것을 생각하게 되었다. 그러면 어떻게 해야 할까? 여러 가지 생각을 하였고, 배열 num의 길이를 수정하기로 하였다. 자연수를 42로 나누어 나올 수 있는 나머지가 0~41까지 총 42가지의 경우이므로 num배열의 길이를 42로 설정을 해주었다.
<해설>
res = arr [j] % 42; 의 코드를 통해 해당 배열 요소의 수를 42로 나눈 나머지가 res값에 저장되게 된다.
num [res] += 1; 예를 들어 res = 32라면, 배열 요소 값이 0 이였던, num의 33번째 요소가 1이 되는 것이다.
나올 수 있는 나머지의 경우의 수가 0~41까지라고 하였었는데, num [0]이면 나머지가 0인 경우이고,
num [21]이면 42로 나눈 나머지가 21인 경우이다.
나올 수 있는 나머지의 경우들을 각 배열의 인덱스 넘버로 정해준 것이다.
if (num [g] >= 1) 만약 어떤 배열 요소에 1 이상의 값이 들어있다면 그 해당 배열 요소의 인덱스 넘버에 해당하는 수가 한 번이라도 42로 나눈 나머지로 나왔었다는 것이다. 그러므로 이의 경우 k값이 증가하게끔 만들어 서로 다른 나머지의 개수가 몇 개인지 구할 수 있도록 하였다.
<참고>
arr[0] = 10; 은 배열 arr의 첫번쨰 요소에 10을 저장하라는 뜻이다.
arr[4] = 5; 는 배열 arr의 5번째 요소에 5를 저장하라는 뜻이다.
배열의 첫번째 요소를 지칭할때 사용되는 숫자는 1이아닌 0이다. 즉, 배열의 위치정보를 명시하는 인덱스 값은 1이아닌 0에서 부터 시작한다.