문제
0보다 크거나 같고, 99보다 작거나 같은 정수가 주어질 때 다음과 같은 연산을 할 수 있다.
먼저 주어진 수가 10보다 작다면 앞에 0을 붙여 두 자리 수로 만들고, 각 자리의 숫자를 더한다. 그 다음, 주어진 수의 가장 오른쪽 자리 수와 앞에서 구한 합의 가장 오른쪽 자리 수를 이어 붙이면 새로운 수를 만들 수 있다. 다음 예를 보자.
26부터 시작한다. 2+6 = 8이다. 새로운 수는 68이다.
6+8 = 14이다. 새로운 수는 84이다.
8+4 = 12이다. 새로운 수는 42이다.
4+2 = 6이다. 새로운 수는 26이다.
위의 예는 4번 만에 원래 수로 돌아올 수 있다. 따라서 26의 사이클의 길이는 4이다.
N이 주어졌을 때, N의 사이클의 길이를 구하는 프로그램을 작성하시오.
풀이
먼저, 처음 숫자를 저장해두어야 한다. 앞으로 비교 대상이 될 것이므로
그리고 사이클의 횟수를 저장할 count변수도 설정한다.
int originalNumber; int count = 1;
cin >> originalNumber; // 처음 숫자 저장
int number = originalNumber; // 비교 대상에 일단 저장
그 후 반복문을 설정 해주어야하는데 While문의 조건으로 "처음 숫자가 새로운 숫자와 같은지?" 를 넣어준다.
만약, 다르다면 사이클의 횟수가 1 증가한다. (처음부터 사이클이 돌기 시작한 것이므로 count = 1 부터 시작)
while (originalNumber != GetNewNumber(number))
{
number = GetNewNumber(number);
count++;
}
cout << count; // 사이클 횟수를 출력
다음은 GetNewNumber 함수이다.
문제에 주어진대로 일의 자리와 십의자리를 잘 조합해서 새로운 숫자를 얻어낸다.
int GetNewNumber(int num)
{
if (num < 10) // 한 자리 수면
{
return num * 10 + num;
}
else if (num >= 10) // 두 자리 수면
{
return (GetOne(num) * 10) + GetOne((GetTen(num) + GetOne(num)));
}
}
다음은 각 자리의 숫자를 얻어내는 GetOne(), GetTen() 함수이다.
// 일의 자리 추출
int GetOne(int n)
{
if (n >= 10) // 두 자리면 계산
{
return n - (n / 10) * 10;
}
else return n; // 한 자리면 그냥 추출
}
// 십의 자리 추출
int GetTen(int n)
{
if (n >= 10) // 두 자리면 계산
{
return n / 10;
}
else return 0; // 한 자리면 0 추출
}
간단한 사칙연산 계산대로 자릿 수를 추출해낼 수 있다.
전체코드
#include <iostream>
using namespace std;
int GetNewNumber(int n);
int GetOne(int n);
int GetTen(int n);
int main()
{
int originalNumber; int count = 1;
cin >> originalNumber; // 처음 숫자 저장
int number = originalNumber; // 비교 대상에 일단 저장
// 새로운 숫자를 가져오기를 반복하면서 같아지면 종료
while (originalNumber != GetNewNumber(number))
{
number = GetNewNumber(number);
count++;
}
cout << count; // 사이클 횟수를 출력
}
// 새로운 숫자를 얻는 함수
int GetNewNumber(int num)
{
if (num < 10) // 한 자리 수면
{
return num * 10 + num;
}
else if (num >= 10) // 두 자리 수면
{
return (GetOne(num) * 10) + GetOne((GetTen(num) + GetOne(num)));
}
}
// 일의 자리 추출
int GetOne(int n)
{
if (n >= 10) // 두 자리면 계산
{
return n - (n / 10) * 10;
}
else return n; // 한 자리면 그냥 추출
}
// 십의 자리 추출
int GetTen(int n)
{
if (n >= 10) // 두 자리면 계산
{
return n / 10;
}
else return 0; // 한 자리면 0 추출
}
결과
26
4
잠을 못 자서 그런지 While문 조건에 오류가 있었는데, 그 오류를 못 찾아서 한시간 가량 헤맨 것 같다.
개인적으로 단순하지만 은근 까다로웠던 재미있는 문제였다고 생각한다.
이로써, 단계별 문제풀이 반복문 파트가 끝이 났다!
'백준 알고리즘 단계별 풀이 (문제 수) > 반복문 (14)' 카테고리의 다른 글
[C++] EOF를 활용한 두 수의 합 입력받기 (0) | 2022.06.17 |
---|---|
[C++] A + B / 두 수의 합 출력 - 0 입력 시 종료 (0) | 2022.06.17 |
[C++] 배열에서 x보다 작은 숫자 출력하기 (0) | 2022.06.17 |
[C++] 별 찍기 - 2 / 오른쪽 정렬로 찍기 (0) | 2022.06.17 |
[C++] 별 찍기 - 1 (0) | 2022.06.17 |