캐또's coding

1065 - 한수 - node.js 본문

기초 공부/백준 문제 풀이

1065 - 한수 - node.js

JS_K_coding 2022. 8. 20. 11:02

문제

어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오. 

입력

첫째 줄에 1,000보다 작거나 같은 자연수 N이 주어진다.

출력

첫째 줄에 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력한다.

예제 입력 1 복사

110

예제 출력 1 복사

99

예제 입력 2 복사

1

예제 출력 2 복사

1

예제 입력 3 복사

210

예제 출력 3 복사

105

예제 입력 4 복사

1000

예제 출력 4 복사

144

예제 입력 5 복사

500

예제 출력 5 복사

119

출처

  • 문제를 번역한 사람: baekjoon
  • 어색한 표현을 찾은 사람: bdh3313
  • 잘못된 데이터를 찾은 사람: djm03178
  • 데이터를 추가한 사람: jh05013

알고리즘 분류


등차수열과 한수라는 단어가 등장해서 패닉에 휩싸였다. 등차수열도 들어본지 오래인데 한수는 또 뭔가 싶다. 문제를 이해하는데 애를 먹다가, 

https://www.acmicpc.net/board/view/25689

 

글 읽기 - 문제 이해가 안됩니다

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

문제의 이해를 도와주는 매우 천사 같은 글을 발견했다. 입력에서 주어진 수를 그냥 수로 봤는데, 수열로 보고 해결해나가면 되는 것이었다.

 

간단히 말하자면?
1. 모든 숫자들을 수열로 봐라: 110이라면 '백십'이 아니라 [ 1 1 0 ] 길이 3짜리 1과 1과 0으로 이뤄진 수열이라 생각해라.
2. 등차수열은 일정한 차가 있으면 된다. 111? 등차수열이다. 0씩 일정한 차이가 있다. 146? 아니다 +3이다가 +2가 된다. 101? 아니다. 1 줄었다가 1이 늘었다.
3. 그래서 문제는 어떻게 하냐? 1부터 시작해서 주어진 숫자 N까지 하나씩 한수인지 아닌지 확인해서 그 갯수를 줄력하면 된다.
예) 1? 등차수열이다. 2? 등차수열이다...... 110? 아니다. 111? 등차수열이다....

숫자가 아니라 수열로 문제를 봐야 했다.

예제 입력 1은 110이라고 되어 있다. 이것을 숫자라고 생각해서 그러니까 숫자인 '백십'이라고 생각해서 등차수열을 어디서 찾을 수 있지? 라고 혼란에 빠졌었다. 숫자 '백십'이라고 생각하지 말고 1 1 0 이렇게 생긴 길이가 3짜리인 1과 1과 0이 들어있는 수열이라고 생각하면 된다. 예시로 946은? 길이 3짜리 9와 4와 6으로 이뤄진 수열이 된다. 

 

각 자리가 등차수열이라는 말은?

등차수열은 쉽게 생각해보자면, 일정한 규칙이 있는 수의 나열(혹은 동''한 ''가 있는 '수열')이라고 생각해볼 수 있을 것이다. 1 2 3 4 5 이것은 길이가 5짜리인 1씩 늘어나는 수열, 등차수열이다. 1 1 1 이것은 길이가 3짜리인 등차수열이다. 8 6 4 2 이것은 길이 4인 2씩 줄어드는 등차수열이다. 각 자리가 등차수열이라는 말이 복잡한데, 위의 수열로 봐야한다는 말처럼 몇 번째 자리 수인지 어떤 수인지 생각하지 말고 그냥 수열이라고 생각해보자, 135 '백삼십오' 이것을 수열이라고 생각한다면? [ 1 3 5 ] 수열 속 세 숫자인 1과 3과 5. 여기서 1과 3은 2차이가 난다. 다시 3과 5는 2차이가 난다. 아! 이 수열은 2씩 늘어나는 수열이다. 즉, 등차수열이다!

 

한수인지 판단은?

각 자리 이런 말 생각하지 말고, 그냥 그 수가 등차수열인지 보라는 뜻이다. 1 그냥 1 이건 등차수열일까? 등차수열이다. 일정하니까. 2는? 3은? 이런 식으로 1부터 9까지는 등차수열로 볼 수 있다. 10은? 등차수열이다. 1 0이니까 1씩 줄어드는 일정한 차이가 있다. 11은? 1 1이니까 일정하다. 1 2는? 마찬가지 13, 14, 15, 16 모두 마찬가지로 길이 2짜리에 일정한 차가 있기 때문에 등차수열의 모습을 하고 있다고 봐야 한다.

예시: 19 => 등차수열이다. 길이 2짜리 8씩 늘어나는 등차수열이다.

예시: 83 => 등차수열이다. 길이 2짜리 5씩 줄어드는 등차수열이다.

예시: 210 => 등차수열이다. 길이 3짜리 1씩 줄어드는 등차수열이다.

예시: 153 => 등차수열이 아니다. 길이 3짜리 처음에 4가 늘어났다가 2가 줄어든다. 일정한 차가 없다.

예시: 107 => 등차수열이 아니다. 길이 3짜리 1이 줄었다가 7이 늘어서 일정하지 않다.

※ 1부터 9까지, 다시 10부터 99까지는 무조건 등차수열로 나올 수 밖에 없음을 알 수 있다.

 

문제에서 입력은 자연수N <= 1000으로 주어진다. 문제를 어떻게 해결해 볼 수 있을까? 236이 주어졌다면? 012인덱스 숫자에 있는 것으로 봐서 0에서 1까지의 차이로 1에서 2까지 계산이 되면 true 아니면 false로 보자.

ABC => if ( A-B == B-C ) { 한수 }

 

const input = Number(require("fs").readFileSync("/dev/stdin").toString().trim());
let count = 0;
for (i = 0; i <= input; i++) {
  if (i < 100 && i != 0) {
    count++;
  } else if (i > 99 && i < 1000) {
    if (((i % 1000) - (i % 100)) / 100 - ((i % 100) - (i % 10)) / 10 == ((i % 100) - (i % 10)) / 10 - (i % 10)) {
      count++;
    }
  }
}
console.log(count);

for문을 돌면서 다음의 계산을 한다. for문의 범위는 0부터 input까지다.

1. 1부터 99까지는 그냥 카운트에 +1해준다.

2. 100부터는 다음의 과정을 거친다. 백의자리수 - 십의자리수가 십의자리수-일의자리수와 같은지 본다. 같다면 카운트에+1해준다.

3. 1000은 계산하지 않는다. 카운트되지도 않는다.

4. for문을 돌고 나서 카운트를 출력한다.

이전 문제를 풀면서 각 자리 숫자를 구하는 방법을 익혀서 적용하는 것은 금방 진행했다. 문제를 이해하는 과정이 오래 걸렸을 뿐 그에 맞는 코드를 작성하는 것도 어렵지 않다.

'기초 공부 > 백준 문제 풀이' 카테고리의 다른 글

11720 - 숫자의 합 - node.js  (0) 2022.08.20
11654 - 아스키 코드 - node.js  (0) 2022.08.20
4673 - 셀프 넘버 - node.js  (0) 2022.08.19
4344 - 평균은 넘겠지 - node.js  (0) 2022.08.19
8958 - OX퀴즈 - node.js  (0) 2022.08.18
Comments