1065번: 한수(BOJ C/C++)
사용 언어: C
문제
어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 1,000보다 작거나 같은 자연수 N이 주어진다.
출력
첫째 줄에 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력한다.
풀이
1부터 99는 무조건 한수다. 좀만 생각해보면 왜 그런지 알 수 있다.
100부터 1000은 직접 그 수까지가 한수인지 계산해봐야 하기 때문에 hansoo() 함수를 만들어서 계산을 한다.
100부터 abc라는 세 자릿수를 a,b,c 를 각각 백의 자릿수, 십의 자릿수, 일의 자릿수로 뽑아서 수열을 이루는지 검사(a-b=b-c)하면 한수의 개수를 알 수 있다. 또한 1~99는 한수이므로 99를 더해주는 것을 잊어주면 안 된다.
1000은 한수일 수가 없으므로 100<=N<=999에 추가해 100<=N<=1000으로 바꿔준다. (hansoo(999)==hansoo(1000))
#include <stdio.h>
int hansoo(int n);
int main()
{
int N, count, add;
scanf("%d",&N);
if(1<=N && N<=99){
count = N;
}
if(100<=N && N<=1000){
add = hansoo(N);
count = 99 + add;
}
printf("%d\n",count);
return 0;
}
int hansoo(int n){
int count;
for(int i=100; i<=n; i++){
int a = i/100;
int b = (i-a*100)/10;
int c = (i-a*100-b*10)%10;
if(b-a==c-b){
count++;
}
}
return count;
}
느낀 점
다른 사람들의 풀이를 보다 보니 역시 내 코드에 아쉬운 점을 찾을 수 있었다.
아래의 코드가 쓰는데 너무 지저분하고 비효율적인 것이었다.
int a = i/100;
int b = (i-a*100)/10;
int c = (i-a*100-b*10)%10;
더 깔끔하게 바꾼 코드는 아래의 코드와 같다.
int a = i/100;
int b = (i%100)/10;
int c = (i%100)%10;
생각해보면 당연한 것이다.
십의 자릿수인 b는 세 자릿수인 i를 100으로 나눈 나머지가 bc이고, 거기다 10을 나누면 당연히 b가 나온다.
일의 자리수인 c는 세자리수인 i를 100으로 나눈 나머지 bc에 또 10으로 나눈 나머지이다.
이렇게 간단하게 표현할 수 있는 걸 생각을 좀만 더 안 해가지고 내 지저분한 코드처럼 표현하는 것은 좀 아쉽긴 하다...
지금은 내가 코딩을 잘 못하는 단계니까 이런저런 표현을 바꿀 수 있는지 생각해보면서 하자. 그리고 코드들을 좀 더 수학적으로 생각할 수 있는 능력을 길러야 할 것 같다. 그러다 보면 언젠가는 많은 생각을 하지도 않아도 코드들을 깔끔하게 구현을 할 수 있을 거라고 생각한다.
'BOJ > 브루트 포스' 카테고리의 다른 글
1018번: 체스판 다시 칠하기 (BOJ JAVA) (0) | 2023.03.14 |
---|