https://www.acmicpc.net/problem/1065
어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.
예제가 이해가 안 갔다. 등차수열인데 왜 110이 99나 나오는지 몰랐다.
비교할 숫자 자체가 100 101 102 103 104 105 106 107 108 109 110이라고만 생각해서 99가 어이가 없었다.
https://www.acmicpc.net/board/view/25689
이 백준 질문 게시글을 보고 깨달았다.
각각의 수를 하나의 수열로 보고 판단하는 것이라서 1부터 9까지는 길이가 1인 등차수열,
10부터 99까지는 길이가 2이고 공차가 양수나 음수인 등차수열로 보는 것이다.
간단히 말하면 1부터 99까지 전부 등차수열이다.
우리는 100부터 계산하면 된다.
계산은 숫자를 각 자릿수로 나눠 차이를 비교하는 함수 IsHanNum()을 구현했다.
bool IsHanNum(int N) {
int cur = N, prev = -1, diff = -1000;
while (cur != 0) {
//처음 시작일 때
if (prev == -1) {
prev = cur % 10;
cur /= 10;
continue;
}
//두번째 순서일때
if (diff == -1000) {
diff = prev - (cur % 10);
prev = cur % 10;
cur /= 10;
continue;
}
//등차수열이 아닌 경우
if (diff != (prev - (cur % 10))) {
return false;
}
prev = cur % 10;
cur /= 10;
}
return true;
}
반복문으로 짰기 때문에 필요한건 이전 자리수 정보인 prev, 차이값인 diff 변수가 필요하다.
지금 봤는데 cur은 필요없다. 원본 수 N이 필요할까봐 저렇게 접근했다.
처음 시작할때는 prev든 diff든 정보가 없으므로 prev만 설정해주고 continue한다.
두 번째 반복문일때는 prev는 있지만 diff가 없으므로 diff값을 설정해주고 continue한다.
그다음 반복문 부터는 자리수간의 차이가 발생할때마다 diff와 비교해 다르다면 바로 false를 return한다.
#include<iostream>
using namespace std;
bool IsHanNum(int N) {
int cur = N, prev = -1, diff = -1000;
while (cur != 0) {
//처음 시작일 때
if (prev == -1) {
prev = cur % 10;
cur /= 10;
continue;
}
//두번째 순서일때
if (diff == -1000) {
diff = prev - (cur % 10);
prev = cur % 10;
cur /= 10;
continue;
}
//등차수열이 아닌 경우
if (diff != (prev - (cur % 10))) {
return false;
}
prev = cur % 10;
cur /= 10;
}
return true;
}
int main() {
int N, Ans = 0;
cin >> N;
for (int i = 1; i <= N; i++) {
if (IsHanNum(i)) Ans++;
}
cout << Ans;
}
주의할점은 처음에 prev도 -1로 초기화를 해주고 똑같이 diff도 -1로 초기화를 해줬다.
당연히 자리수간의 차이가 -1도 발생하므로 diff를 -1로 설정해버리면 안 된다.
따라서 절대 나올수없는 값으로 설정했다ㅏ.
사실 자릿수의 차이가 9~ -9가 최대이므로 10정도로만 해도된다.
1000은 그냥 생각나는 숫자 아무거나 했다.