1. 문제
어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.
--- More Details ---
등차수열이란?
연속하는 두 항의 차이가 모두 일정한 수열
식으로 나타내면 다음과 같다.
한수란?
각 자리수들이 등차수열을 이루는 수
한수의 예를 들어보면,
123(공차 1) , 2468(공차 2) , 951(공차 -4), 등등이 있다.
세자리 수 이상인 수는 이렇게 쉽게 한수를 생각해 낼 수 있는데, 한자리수와 두자리수는 한수를 어떻게 구할까?
한자리수와 두자리수는 모두 한수이다.
한자리수인 경우,(1,2,3,4...9) 따로 비교할 숫자가 없기 때문에 그 자체로 한수라 한다. 뭐 그래도 한수인 이유를 굳이 살펴보자면, 01(공차1) 02(공차2)... 09(공차9) 라고 볼수 있다.
두자리수인 경우, 십의자리와 일의자리의 차가 공차가 되면서 한수라 할 수 있다. 10(공차 -1) 48(공차 4) 92(공차 -7)...
따라서 모든 한자리수와 두자리수는 한수이다. 이점에 유의하며 문제를 풀어야 한다
추가로 11, 22, 99, 333, 이 수들은 한수일까?맞다. 공차가 0인 한수들이다.
2. 알고리즘 및 풀이
나는 함수를 main, getDigits, arithmetic_sequence함수 이렇게 세개 만들었다.
main은 말 그대로 main함수
getDigits함수는 각 자릿수를 뽑아내는 함수로, int형 배열을 반환한다.
arithmetic_sequence함수는 등차수열(arithmetic_sequence)인지 아닌지를 판별하는 함수이다.
getDigits함수 (각 자릿수 뽑아내어 배열로 저장하기)
public static int[] getDigits(int n){
int[] digits= new int[3];
for(int i=0;i<3;i++) {
digits[i]=n%10;
n=n/10;
}
return digits;
}
이제는 바로바로 짤 수 있어야 하는 함수중에 하나이다. 일단 문제에서 n은 1000이하의 수라 하였고, 우리가 100미만인 수(한자리수와 두자리수)는 따로 계산하고, 1000은 한수가 아니기 때문에 세자리수만 판정하면 된다. 따라서 각 자릿수를 얻는 것 또한 세자리 수만 계산할 것이기 때문에 digits배열은 크기가 3이면 된다.
일의자리부터 10을 나눈 나머지를 배열[0]에 저장하고, 10을 나누어 몫만 다시 n에 저장하고, ... 이렇게 반복하면된다.
246을 예로들어 표현하면
i=0일때, 246%10 = 6 이므로, digits[0]=6, n=(246/10=)24
i=1일 때, 24%10 = 4 이므로, digits[1]=4, n=(24/10=)2
i=2일때, 2%10=2 이므로 digits[2] = 2, n=(2/10=)0
반복문 종료
그리고 getDigits함수는 digits배열을 반환한다.
arithmetic_sequence 함수 (각 자리수가 등차수열인지 아닌지 판별하기)
한수(각 자릿수가 등차수열인 수)이면 cnt=1을 저장하여 반환한다.
1. 100미만의 수(한자리수, 두자리수)는 한수이므로 cnt=1이다.
2. n이 1000이라면 한수가 아니기때문에, cnt=0이다. 0이 아닌 다른수로 저장해도 상관없다.
3. 그 외(세자리수) getDigits함수를 통해 각 자릿수를 저장한 배열을 불러와 등차수열인지 아닌지 판별한다.
등차수열을 판별하는 방법은 (세자리수-두자리수) 와 (두자리수-한자리수)가 같으면 된다. 거꾸로 (한자리수 - 두자리수) 와 (두자리수 - 세자리수)가 같으면 된다. 즉, 연속된 수의 공차가 같으면 된다. 공차가 동일하면 cnt=1이다.
public static int arithmetic_sequence(int n) {
int cnt=0;
if(n<100) cnt=1;
else if(n==1000) cnt=0;
else {
int[] digits = getDigits(n);
if(digits[2]-digits[1]==digits[1]-digits[0]) cnt=1;
}
return cnt;
}
main함수
int n = sc.nextInt();
int result=0; //result: 한수의 개수를 저장
for(int i=1;i<=n;i++) {
if(arithmetic_sequence(i)==1) result++;
}
System.out.println(result);
n에 숫자를 입력 받아 저장하고 1부터 n까지 반복문을 돌려 cnt의 개수, 즉 한수의 개수를 세어주면 된다. arithmetic_sequence함수를 불러 그 함수가 반환하는 값이 1이면 한수이므로 result를 1 증가 시키면 된다.
3. 전체 코드
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int result=0;
for(int i=1;i<=n;i++) {
if(arithmetic_sequence(i)==1) result++;
}
System.out.println(result);
sc.close();
}
public static int[] getDigits(int n){
int[] digits= new int[3];
for(int i=0;i<3;i++) {
digits[i]=n%10;
n=n/10;
}
return digits;
}
public static int arithmetic_sequence(int n) {
int cnt=0;
if(n<100) cnt=1;
else if(n==1000) cnt=0;
else {
int[] digits = getDigits(n);
if(digits[2]-digits[1]==digits[1]-digits[0]) cnt=1;
}
return cnt;
}
}
4. 링크
'Computer Science > 자료구조와 알고리즘' 카테고리의 다른 글
[JAVA] 백준 11720번 : 숫자의 합 (0) | 2021.02.03 |
---|---|
[JAVA] 백준 11654번 : 아스키 코드 (0) | 2021.02.03 |
[JAVA] 백준 4673번 : 셀프넘버 (0) | 2021.01.22 |
[JAVA] 백준 4544번 : 평균은 넘겠지 (1) | 2021.01.17 |
[JAVA] 백준 8958번 :OX퀴즈 (0) | 2021.01.17 |