일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 프로그래머스연습문제
- 그리디
- 브루트포스알고리즘
- 프로그래머스
- 큐
- 해시를사용한집합과맵
- 프로그래머스sql
- 사칙연산
- 논문리뷰
- Image Classification
- 정수론
- 백준
- C++
- MySQL
- SQL
- 그리디알고리즘
- C언어
- 소수판정
- 이분탐색
- 다이나믹프로그래밍
- C
- 구현
- 프로그래머스코딩테스트
- 백준알고리즘
- 자료구조
- 문자열
- 이진탐색
- 수학
- 논문구현
- 정렬
- Today
- Total
초보 개발자의 이야기, 릿허브
[C++] 백준 1475번 방 번호 본문
1. 문제이해
https://www.acmicpc.net/problem/1475
다솜이는 자기 방 번호를 플라스틱 숫자로 붙이려고 한다.
플라스틱 숫자는 0 ~9 한 세트로 판매하며, 6, 9는 서로 뒤집어서 사용가능하다.
다솜이의 방 번호가 주어질 때, 필요한 세트의 개수를 출력하는 것이 목표이다.
2. 문제풀이
다솜이의 방 번호가 주어질 때, 필요한 숫자 세트의 개수를 출력하는 문제이다.
단, 숫자세트에는 0 ~ 9 까지의 숫자가 들어있으며, 6과 9는 서로 뒤집어서 사용가능하다.
6과 9가 서로 호환가능하다는 점에 유의해야한다.
아래 예제를 통해 풀이방법을 자세히 알아보자.
<예제 입력 1>
다솜이의 방 번호가 9999
다솜이의 방 번호를 살펴보면, 9가 4번 필요하다.
9는 4개 이지만 6을 이용해 9를 만들 수 있으므로, 사실상 2세트면 위와 같은 숫자를 만들 수 있다.
<예제 입력 2>
다솜이의 방 번호가 122
다솜이의 방 번호를 살펴보면, 1이 1번, 2가 2번 필요하다.
한 세트에 0 ~9 까지의 숫자가 하나씩 들어있으므로,
1, 2 를 1개씩 얻기 위해 한 세트, 2를 한번 더 얻기 위해 한 세트를 구매해야하므로, 총 2세트가 필요하다.
<예제 입력 n>
다솜이의 방 번호가 1126699
다솜이의 방 번호를 살펴보면 1이 2번, 2가 1번, 6이 2번, 9가 2번 필요하다.
여기서, 6과 9 같은 특수 경우를 제외한 경우들 중 최대 빈도수는 1인 2번이다.
6과 9는 각각 2번, 총 4번 나타났으나,두 숫자가 서로 호환 가능하므로, 2번 필요하다.
즉, 6과 9는 (6의 빈도수 + 9의 빈도수) / 2 + 1 (홀수의 경우 + 1 필요) 만큼 필요하다.
6, 9의 빈도수와 6, 9를 제외한 숫자의 최대 빈도수를 비교, 더 큰 값이 최종적으로 필요한 세트 수가 된다.
해당 경우, 6과 9의 빈도수 = (2 + 2) / 2 = 2
6과 9를 제외한 숫자의 최대 빈도수 = 2
로 같으므로, 최종적으로 필요한 세트수는 2세트이다.
위 예제들을 통해 알 수 있듯, 해당 문제의 풀이방법은 다음과 같이 정리할 수 있으며,
작성한 소스코드는 다음과 같다.
1. 입력받은 방 번호의 각 숫자의 빈도수 체크
2. 6, 9를 제외한 숫자들 중 최대 빈도수 값 체크
3. 6, 9의 빈도수와 2에서 구한 가장 큰 빈도수를 비교, 더 큰 값을 채택
3. 소스코드
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N; // 방 번호
int num[10] = { 0, }; // 0 ~ 9 숫자들의 빈도수
int remain; // 빈도수를 구하기 위한 변수
int set; // 최종적으로 필요한 세트 수
int six_nine; // 6과 9의 빈도수의 합
cin >> N;
// 1. 입력받은 방 번호의 각 숫자의 빈도수 체크
while (N > 0) {
remain = N % 10;
num[remain]++;
N = N / 10;
}
// 2. 6, 9를 제외한 숫자들 중 최대 빈도수 값 체크
set = 0;
for (int i = 0; i < 10; i++) {
if (i == 6 || i == 9) {
continue;
}
if (set <= num[i]) {
set = num[i];
}
}
// 3. 6, 9는 서로 호환가능하므로 빈도수 더해줌.
six_nine = num[6] + num[9];
// 4. 6, 9의 빈도수와 2에서 구한 가장 큰 빈도수 비교
// 더 큰 값이 필요한 세트의 개수
// 4 - 1. 6, 9의 빈도수가 홀수인 경우
if (six_nine % 2 == 1) {
if (set < six_nine / 2 + 1) {
set = six_nine / 2 + 1;
}
}
// 4 - 2. 6, 9의 빈도수가 짝수인 경우
else {
if (set < six_nine / 2) {
set = six_nine / 2;
}
}
cout << set;
return 0;
}
2. 문제풀이에서 도출한 방법을 통해 작성한 코드이다.
먼저 방 번호(N)를 입력받고, while문을 통해 1. 방 번호의 각 숫자들의 빈도수를 체크한다.
숫자들의 반도수를 체크 한 뒤, 2. 6, 9를 제외한 숫자들 중 최대 빈도수 값을 체크해 set에 대입한다.
3. 6, 9의 빈도수를 더해준 뒤 (호환가능하므로), 4. 6, 9의 빈도수와 2.에서 구한 최대 빈도수 값을 비교한다.
만약, 6, 9의 빈도수의 합, 즉, six_nine 변수가 홀수인 경우, + 1을 해주어 비교해주고,
짝수라면 해주지 않은 채 값을 비교한다.
(예를 들어 1166999 의 경우, 6, 9 제외 최대 빈도수는 1의 2번. 6, 9의 빈도수는 5번이다.
해당 경우에는 1, 6, 9 한 세트, 다시 동일하게 한 세트, 그리고 남은 9 한세트, 총 3세트가 필요하다.
하지만 만약, 6, 9의 빈도수는 5번인데, 2로 나누어주기만 하면, 2가 나오게 되고, 총 필요 세트 수는 2가 된다.
이러한 경우를 방지하기 위해 6, 9의 빈도수가 홀수이면, 2로 나눈뒤 1을 더해준다.)
주석 없는 코드는 왼쪽 아래 더보기를 참고 바랍니다.😊
<주석 없는 코드>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N;
int num[10] = { 0, };
int remain;
int set;
int six_nine;
cin >> N;
while (N > 0) {
remain = N % 10;
num[remain]++;
N = N / 10;
}
set = 0;
for (int i = 0; i < 10; i++) {
if (i == 6 || i == 9) {
continue;
}
if (set <= num[i]) {
set = num[i];
}
}
six_nine = num[6] + num[9];
if (six_nine % 2 == 1) {
if (set < six_nine / 2 + 1) {
set = six_nine / 2 + 1;
}
}
else {
if (set < six_nine / 2) {
set = six_nine / 2;
}
}
cout << set;
return 0;
}
문제에 대한 지적이나 질문은 언제나 감사하게 받고 있습니다.😊
'코딩테스트 > 📗 백준 (BOJ)' 카테고리의 다른 글
[C++] 백준 2193번 이친수 (0) | 2022.02.14 |
---|---|
[C++] 백준 2548번 대표 자연수 (0) | 2022.02.10 |
[C++] 백준 13022번 늑대와 올바른 단어 (0) | 2022.02.07 |
[C++] 백준 1158번 요세푸스 문제 (0) | 2022.02.04 |
[C++] 백준 11561번 좌표 정렬하기 2 (0) | 2022.02.03 |