[백준 1065 - C++] 한수

4682 단어 bojboj

문제

풀이

조금만 생각하면 쉽게 풀 수 있는 문제다.
전체 코드는 다음과 같다.

#include <iostream>
#include <cmath>
using namespace std;

int HansuCount(int N, int digit)
{
  if(digit == 1 || digit == 2)
  {
    // 한 자리수일 경우 등차가 0인 등차수열이고
    // 두 자리수일 경우 십의 자리 수와 일의 자리 수 사이의 등차는 항상 일정하므로
    // 1을 리턴하고 함수 종료
    return 1;
  }
  else
  {
    bool isSequence = true; // 등차 수열 여부를 확인하는 bool 변수
    int* numArray = new int[digit]; // 각 자리수를 저장할 배열
    int* diff = new int[digit - 1]; // 각 자리수의 등차를 저장할 배열

    // 각 자리수 구하기
    for(int i = 0; i < digit; i++)
    {
      numArray[(digit - 1) - i] = N % 10;
      N /= 10;
    }

    // 각 자리수 사이의 등차 구하기
    for(int i = 1; i < digit; i++)
    {
      diff[i-1] = numArray[i-1] - numArray[i]; 
    }

    // 모든 등차가 같은지 확인
    for(int i = 1; i < digit - 1; i++)
    {
      if(diff[0] == diff[i])
      {
        isSequence = true;
      }
      else
      {
        // 등차 수열이 아닌 것이 확인되면 바로 빠져나오기
        isSequence = false;
        break;
      }
    }

    // 메모리 해제
    delete[] numArray;
    delete[] diff;

    // 등차수열이면 1, 아니면 0 리턴
    if(isSequence == true)
    {
      return 1;
    }
    else
    {
      return 0;
    }
  }
}

int main()
{
  int N;
  cin >> N;

  int count = 0;  // 등차수열의 수를 셀 정수형 변수
  for(int i = 1; i <= N; i++)
  {
    // 주어진 수 N의 자리수 확인
    int digitCount = 1;
    while(i % ((int)pow(10, digitCount)) != i)
    {
      digitCount++;
    }

    count += HansuCount(i, digitCount);
  }

  cout << count << endl;

  return 0;
}

먼저 main 함수부터 보자.

int main()
{
  int N;
  cin >> N;

  int count = 0;  // 등차수열의 수를 셀 정수형 변수
  for(int i = 1; i <= N; i++)
  {
    // 주어진 수 N의 자리수 확인
    int digitCount = 1;
    while(i % ((int)pow(10, digitCount)) != i)
    {
      digitCount++;
    }

    count += HansuCount(i, digitCount);
  }

  cout << count << endl;

  return 0;
}

자연수 N을 입력받은 후, 등차수열의 수를 셀 정수형 변수를 선언한다.

for문 안을 살펴보면 먼저 주어진 N의 자리수를 확인한다. digitCount 변수는 자리수의 개수를 의미한다.

while문 안에서는 1과 N 사이의 수 i를 10^1, 10^2, 10^3, ... 으로 나눈 나머지를 구해 자리수를 구한다. 나머지 연산에서 나누는 수가 나누어지는 수보다 더 크다면 나누어지는 수가 그대로 나오기때문에, i 값이 그대로 나오기 전까지 계속 반복한다.

그러고나서 현재 수 i와 i의 자리수 digitCount를 HansuCount 함수로 전달한 후, 그 리턴값을 count에 더한다.

모든 과정이 끝나면 count를 출력한다.

이제 HansuCount 함수를 살펴보자.

int HansuCount(int N, int digit)
{
  if(digit == 1 || digit == 2)
  {
    // 한 자리수일 경우 등차가 0인 등차수열이고
    // 두 자리수일 경우 십의 자리 수와 일의 자리 수 사이의 등차는 항상 일정하므로
    // 1을 리턴하고 함수 종료
    return 1;
  }

만약 인수로 주어진 수가 한 자리수거나 두 자리수면 등차수열을 따질 필요가 없으므로, 1을 리턴하고 함수를 종료한다.

  else
  {
    bool isSequence = true; // 등차 수열 여부를 확인하는 bool 변수
    int* numArray = new int[digit]; // 각 자리수를 저장할 배열
    int* diff = new int[digit - 1]; // 각 자리수의 등차를 저장할 배열

    // 각 자리수 구하기
    for(int i = 0; i < digit; i++)
    {
      numArray[(digit - 1) - i] = N % 10;
      N /= 10;
    }

등차 수열 여부를 확인하는 isSequence, 각 자리수에 있는 수를 저장할 배열 numArray, 그리고 각 자리수에 있는 수 사이의 차이를 저장할 diff 배열을 선언한다.

for문 안에서는 numArray에 함수의 인수로 주어진 수의 각 자리수를 저장한다 (ex: 112 -> [1, 1, 2])

    // 각 자리수 사이의 등차 구하기
    for(int i = 1; i < digit; i++)
    {
      diff[i-1] = numArray[i-1] - numArray[i]; 
    }

그러고나서 각 자리에 있는 수 사이의 차이를 계산한 후, diff 배열에 저장한다.

    // 모든 등차가 같은지 확인
    for(int i = 1; i < digit - 1; i++)
    {
      if(diff[0] == diff[i])
      {
        isSequence = true;
      }
      else
      {
        // 등차 수열이 아닌 것이 확인되면 바로 빠져나오기
        isSequence = false;
        break;
      }
    }

diff 배열에 저장된 모든 요소를 비교해 모든 등차가 같은지 확인한다. diff[0] = diff[1], diff[0] = diff[2], ... 이면 diff[0] = diff[1] = diff[2] = ... 과 같으므로 등차수열이기 때문에 isSequence 변수를 true로 바꾼다.

만약 그렇지 않다면 등차수열이 아니라는 뜻이 되므로 isSequence를 false로 바꾸고 for문을 break로 빠져나온다.

    // 메모리 해제
    delete[] numArray;
    delete[] diff;

    // 등차수열이면 1, 아니면 0 리턴
    if(isSequence == true)
    {
      return 1;
    }
    else
    {
      return 0;
    }
  }
}

앞서 사용한 동적 배열들을 해제해준다.
그리고 등차수열이면 1, 아니면 0을 리턴해준다.

좋은 웹페이지 즐겨찾기