문제
두 자연수 A와 B가 있을 때, A%B는 A를 B로 나눈 나머지 이다. 예를 들어, 7, 14, 27, 38을 3으로 나눈 나머지는 1, 2, 0, 2이다.
수 10개를 입력받은 뒤, 이를 42로 나눈 나머지를 구한다. 그 다음 서로 다른 값이 몇 개 있는지 출력하는 프로그램을 작성하시오.
입력
첫째 줄부터 열번째 줄 까지 숫자가 한 줄에 하나씩 주어진다. 이 숫자는 1,000보다 작거나 같고, 음이 아닌 정수이다.
출력
첫째 줄에, 42로 나누었을 때, 서로 다른 나머지가 몇 개 있는지 출력한다.
우선적으로 생각할 수 있는것은 배열을 활용하여 해결할 수 있다.
나머지를 배열의 원소로 저장하는 배열을 만들 생각을 하고
우선 입력값을 저장할 배열 (배열 A[10])을 만들었다.(코드를 간략화 하기 위해서는 이 배열을 굳이 만들지 않아도 되긴하다.)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int A[10];
int B[42] = { 0 };
int count = 0;
for (int i = 0; i < 10; i++) {
scanf("%d", &A[i]);
}
for (int i = 0; i < 10; i++) {
if (B[A[i] % 42] == 0) {
B[A[i] % 42] = 1;
count++;
}
}
printf("%d", count);
return 0;
}
나머지가 한번이라도 나오면 배열 B의 값을 1로 바꾸도록 설정하고 count를 1 올린다.
그리고나서 count를 출력하면 배열B에서의 1의 값을 갖는 나머지들을 인덱스넘버로 확인할 수 있다.
아래는 확인차 배열B를 출력하도록 나타내었다.
알고리즘을 정리하자면 다음과 같다.
1.입력값을 가지는 배열을 만든다.
2.나머지 값을 가지는 배열을 인덱스 넘버가 각각의 나머지를 의미하도록 배열을 만든다.
3.나머지 값에 따라 인덱스 넘버가 부여되고 그 배열의 원소의 값을 1로 수정한다.
4.1로 수정된 횟수만큼 count를 올려 서로다른 원소의 개수를 센다.
5.count를 출력한다.
하지만 위 코드로는 나머지들이 어떤 종류가 나왔는지만 확인할 수 있고, 어떤 나머지 값이 여러번 나온다면 몇 번 나왔는지는 확인할 수 없다. 따라서 다음과 같이 코드를 수정하면 나머지값이 몇번 씩 나왔는지도 확인할 수 있다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int A[10];
int B[42] = { 0 };
int count = 0;
for (int i = 0; i < 10; i++) {
scanf("%d", &A[i]);
}
for (int i = 0; i < 10; i++) {
//B배열의 값을 0에서 1로 바꾸는것이 아니라 나온 횟수만큼 1을 증가하도록 변경
B[A[i] % 42] += 1;
count++;
}
for (int i = 0; i < 42; i++) {
printf("B[%d]=%d\n", i, B[i]);
}
printf("%d", count);
return 0;
}
원래 정상적인 출력값으로는 6을 출력해야하는데 10이 나오는 것을 확인할 수 있다.
이는 조건문이 사라지면서 블록의 반복을 할 때 마다 그냥 count를 증가시켜서 그렇다.
따라서 count를 따로 반복문을 만들어 횟수를 세어주는것이 좋다.
수정된 코드는 다음과 같다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int A[10];
int B[42] = { 0 };
int count = 0;
for (int i = 0; i < 10; i++) {
scanf("%d", &A[i]);
}
for (int i = 0; i < 10; i++) {
B[A[i] % 42] += 1;
}
for (int i = 0; i < 42; i++) { //배열의 서로 다른 수를 세어주기 위한 또 다른 반복문
if (B[i] >= 1) { //주의할점은 B[A[i]%42]가아니라 B[i]로 확인해야한다.
count++;
}
}
for (int i = 0; i < 42; i++) { //확인차 배열을 출력하는 코드 정답제출에는 필요없다.
printf("B[%d]=%d\n", i, B[i]);
}
printf("%d", count);
return 0;
}
주석에 적었듯이
배열 B에서 1이상의 값을 갖는 인덱스들을 세는것은
이미 저장된 배열 B의 원소 B[0]~B[41]까지에서 확인하는 것이기 때문에 B[i]로 확인하며 count++하는것이 옳다.
'DSA' 카테고리의 다른 글
최대값,최소값,중앙값 찾기 알고리즘 (1) | 2024.06.25 |
---|---|
백준 10811번 배열 부분 역순 정렬 (0) | 2024.06.23 |
백준 5597번 배열의 차집합 활용 (0) | 2024.06.21 |
다익스트라 알고리즘 (Dijkstra Algorithm) (0) | 2024.06.06 |
포인터 연습 예제3 (참조에 의한 호출, call-by-reference)(함수에서 2개 이상의 값 동시 반환) (1) | 2024.06.04 |