어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.
첫째 줄에 1,000보다 작거나 같은 자연수 N이 주어진다.
첫째 줄에 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력한다.
#include<iostream>
using namespace std;
int hanNumber(int n);
int main() {
// 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다.
// 예를들어 숫자 135일 경우 (5 - 3) == (3 - 1)로 풀이, 등차수열을 성립해 한수가 된다.
// 1000보다 작은 자연수 N을 입력받는다.
int inputN;
cin >> inputN;
cout << hanNumber(inputN);
return 0;
}
int hanNumber(int n) {
// 적어도 숫자가 3자리수는 되어야 비교가 가능하다
if (n < 100)
return n;
// 자리수를 담을 배열을 만든다.
int digit = n, size = 0, idx = 0; // 자리수, 배열 사이즈
while (digit > 0) {
digit /= 10;
size++;
}
int* numDigits = new int[size];
int count = 99; // 100이상의 숫자의 최소 한수의 개수는 99이다.
bool isHan = false;
for (int i = 100; i <= n; i++)
{
// 배열에 자리수 값들을 채워넣는다.
idx = 0;
digit = i;
while (digit != 0) {
numDigits[idx] = digit % 10;
digit /= 10;
idx++;
}
// 모든 자리수를 순회하여 한수인지 확인한다.
isHan = false;
for (int k = 0; k < idx - 2; k++) {
isHan = (numDigits[k] - numDigits[k + 1]) == (numDigits[k + 1] - numDigits[k + 2]);
}
if (isHan == true) count++;
}
return count;
}
매번 느끼는 것이지만, 어떻게 풀어나갈 것인지에 대한 부분보다는, 어떤 문제인지 파악하는데 시간이 많이 소요되고 있다. 그래서 등차수열에 대해 다시 복습하고, 너무 막히는 경우 다른사람들의 풀이를 보면서 이해를 통해 다른 방법으로도 푸는 도전을 하고있다.
이번 문제에서도 간단히 100의자리 10의자리 1의자리로 한다면 쉽게 풀 수 있었을 것인데, 최대 수가 바뀐다고하더라도 똑같은 결과를 도출해내는 일반화된 방법으로 풀어보려고 노력했다.
참고 자료 및 사이트 (감사합니다)