ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 1065번 : 한수 - 자바(JAVA)
    알고리즘/백준 2022. 2. 2. 00:01
    728x90

    https://www.acmicpc.net/problem/1065

     

    1065번: 한수

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

    www.acmicpc.net

     

    문제 해석

    어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면 이를 한수라고 한다.

    등차수열은 연속된  두 개의 수의 차가 일정한 수열을 말합니다.

    이때 1보다 크거나 같고 N보다 작거나 같은 한 수의 개수를 출력하는 프로그램을 만들어야 합니다.

     

    등차수열 예시

    1, 3, 5, 7, 9 (차가 2로 일정함)

     

    10, 20, 30, 40, 50 (차가 10으로 일정함)

     

    한수의 예시

    123

    24

    3

    15


    입력

    첫째줄에는 정수 N이 입력됩니다.

     

    제약조건

    1 <= N <= 1000


    출력

    1부터 N사이의 한수의 개수를 출력합니다.

     


    문제 풀이 전 설계

    입력값 받기

    정수 N을 입력받습니다.

     

    핵심로직

    1 <= i <= N 범위에 반복문을 돌면서 한수를 찾아야 합니다.

     

    100 미만의 수들을 모두 한수입니다

    50은 -5씩 작아지는 등차수열로 생각할 수 있습니다.

    51은 -4씩 작아지는 등차수열으로 생각할 수 있습니다.

    3은 모든 정수 n만큼 커지거나 작아지는 등차수열으로 생각할 수 있습니다.

    55는 0씩 커지거나 작아지는 등차수열으로 생각할 수 있습니다.

     

    100 이상의 수부터는 한수인지 확인해야 합니다.

     

    100은 한수가 아닙니다.

    111은 0씩 커지거나 작아지는 등차수열로 생각할 수 있기 때문에 한수입니다.

    123은 1씩 커지는 등차수열으로 생각할 수 있기 때문에 한수입니다.

    135는 2씩 커지는 등차수열으로 생각할 수 있기 때문에 한수입니다.

     

    100 이상의 수부터 한수를 검사하는 로직은 아래와 같습니다

    123을 예시로 들어보겠습니다

    123 % 10 = 3입니다 (이로써 일의 자리의 수를 구할 수 있습니다.)

    123 / 10 = 12입니다.

    12 % 10 = 2입니다. (이로써 십의 자리의 수를 구할 수 있습니다.)

    12 / 10 = 1입니다.

    1 % 10 = 1입니다.( 이로써 백의 자리의 수를 구할 수 있습니다.)

    1/ 10 = 0입니다. (0이면 종료됩니다)

    이렇게 구한 자릿수를 통해 이 수가 등차수열을 이루는지 검사하면 됩니다.


    코드

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.util.ArrayList;
    
    /*
     * BOJ 1065번 : 한수
     * 어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다.
     * 등차수열은 연속된 두 수의 차이가 일정한 수열을 말한다.
     * N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.
     */
    public class Hansu {
    	static int N;
    	static int count = 0;
    
    	public static void main(String[] args) throws NumberFormatException, IOException {
    		// TODO Auto-generated method stub
    		inputNum();
    		searchHansu();
    		printResult();
    	}
    
    	static void inputNum() throws NumberFormatException, IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		N = Integer.parseInt(br.readLine());
    		br.close();
    	}
    
    	static void searchHansu() {
    		for (int i = 1; i <= N; i++) {
    			if (i < 100 || isHansu(i)) {
    				count++;
    			}
    		}
    	}
    
    	static boolean isHansu(int num) {
    		ArrayList<Integer> numSplited = new ArrayList<Integer>(4);
    
    		do {
    			numSplited.add(num % 10);
    			num /= 10;
    		} while (num > 0);
    		
    		int gap = numSplited.get(0) - numSplited.get(1);
    		for (int i = 1; i < numSplited.size() - 1; i++) {
    			if (gap != numSplited.get(i) - numSplited.get(i + 1)) {
    				return false;
    			}
    		}
    
    		return true;
    	}
    	
    	static void printResult() throws IOException {
    		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    		bw.write(count + "\n");
    		bw.flush();
    		bw.close();
    		
    	}
    }

    입출력의 효율성을 위해 inputNum() 메서드에는 bufferedReader를 사용하였으며, outputResult()에는 bufferedWriter를 사용하였습니다.

     

    searchHansu() 메서드는 1부터 N까지 반복하며 i값이 한수인지 검사합니다.

    100보다 작은 경우는 항상 한수이며 100보다 큰 값은 한수인지 검사하기 위해 isHansu() 메서드를 실행합니다.

    isHansu() 메서드는 numSplited ArrayList에 do-while 반복문을 통하여 각 자릿수를 넣어줍니다.

    이때 N은 1000보다 작거나 같은 수 이므로 ArrayList의 크기는 4로 초기화합니다.

    이후에 숫자들 사이의 간격이 일정하지 않다면 false를 반환하고 일정하다면 true를 반환합니다.

    댓글

Designed by Tistory.