ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준/BOJ] 1598번 : 꼬리를 무는 숫자 나열 (JAVA / 자바)
    백준 2022. 1. 29. 16:22

    안녕하세요~ 코딩하는 코알못 코메인입니다.

     

     

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

     

    1598번: 꼬리를 무는 숫자 나열

    첫째 줄에 원숭이가 생각한 두 개의 자연수가 주어진다. 각 수는 10,000,000 이하이다.

    www.acmicpc.net


    - 문제 -

     

    난이도 브론즈 3 문제이다.

    자바에서 입력방식은 scanner와 bufferedreader가 있다.

    자바를 초반에 접하면 처음에 배우는 입력은 scanner이다. scanner가 bufferedreader보다 편하지만 속도가 느리다.

    bufferedreader는 무조건 문자열로 받아오기때문에 정수형이나 실수형 변수에 저장하기 위해서는 입력과 형변환을 해줘야한다.

    더 자세한 내용은 아래 글 참고 하면 좋다.

    https://comain.tistory.com/3

     

    (JAVA / 자바) Scanner 와 Bufferedreader

    안녕하세요~ 코딩하는 코알못 코메인입니다. 이번엔 백준 문제 풀면서 계속 언급될 scanner와 bufferedreader에 대한 간단한 정리를 해볼거다. 자바에서 입력은 scanner와 bufferedreader가 있다. 우선 각자

    comain.tistory.com

     

    풀이 방법

    풀고나서 다른 사람들이 풀이한 것을 보고 한탄했다... 쉬운 방법을 두고 돌아돌아 푼 것을...

    다른 사람들이 푼 방식은 x,y 좌표를 구해서 이동 거리를 구했고, 나는 두 값중 작은 값이 큰 값으로 이동할때마다 횟수를 저장하는 방식으로 구했다.

    x , y좌표를 이용한 방식으로도 풀어보았다. 내 입맛대로 풀었지만 다른 사람들하고 크게 다르진 않을 것이라 생각한다. 두 방식의 코드를 다 올릴 것이고, 참고할 사람은 더 편해보이거나 좋아보이는 그런걸로 하면 될 것 같다.

     


    -풀이-

    좌표로 계산한 코드

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class Main {
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		StringTokenizer st = new StringTokenizer(br.readLine());
    		int A = Integer.parseInt(st.nextToken());
    		int B = Integer.parseInt(st.nextToken());
    		
    		//각 좌표 설정
    		int x1, y1, x2, y2 = 0;
    		
    		//입력값이 4의 배수일 경우 나머지가 0으로 나오기 때문에 y좌표 값을 0으로 한다.
    		//x좌표도 같은 경우다. 딱 맞아 떨어지기 때문에 몫을 그대로 가져온다.
    		if(A % 4 == 0) {
    			x1 = A / 4;
    			y1 = 1;
    		//4의 배수가 아니면 x좌표는 1을 더해주고, y좌표는 나머지를 5에서 빼준다.
    		}else {
    			x1 = (A / 4) + 1;
    			y1 = 5 - (A % 4);
    		}
    		
    		//B좌표도 A좌표와 마찬가지다
    		if(B % 4 == 0) {
    			x2 = B / 4;
    			y2 = 1;
    		}else {
    			x2 = (B / 4) + 1;
    			y2 = 5 - (B % 4);
    		}
    		
    		//두 좌표값중 어느 좌표값이 더 큰지 알 수 없기에 뺀 뒤 절댓값으로 계산한다.
    		System.out.println(Math.abs(x2 - x1) + Math.abs(y2 - y1));
    	}
    
    }

    내가 먼저 푼 노가다식 코드

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class Main {
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		StringTokenizer st = new StringTokenizer(br.readLine());
    		int A = Integer.parseInt(st.nextToken());
    		int B = Integer.parseInt(st.nextToken());
            //A B 두 값중 크고 작은 값을 변수에 넣어준다.
    		int N = Math.min(A, B);
    		int M = Math.max(A, B);
    		int count = 0;
    		
            //무한반복문으로 조건 충족할때까지 반복
    		while(true) {
            	//오른쪽으로 이동하는 반복문이기 때문에 한칸 이동할때마다 최솟값에 4를 더해준다.
               	//count는 이동한 횟수
    			N += 4;
    			count++;
                //N과 M 값이 가로로 같은 경로에 있으면 4를 더하다 보면 같은 값이 된다. 그때 종료.
    			if(N == M) {
    				break;
    			}
                //최대값을 4로 나눈 나머지가 0일떄와 아닐때 범위 식이 달라지기 때문에 나눠 조건을 단다.
    			if((M % 4) == 0 && M - 3 <= N && N <= M) {
    				break;
    			}
    			if((M % 4) != 0 && (1 + ((M / 4) * 4)) <= N && N <= (((M / 4) + 1) * 4)) {
    				break;
    			}
                //위 조건들에 부합하지 않으면서 N에 4를 더했을때 M을 넘어가는 경우가 있다.
                //그런경우에는 N에서 4를 다시 빼주고 count에서도 1을 뺀다.그리고 반복문 종료
    			if(N > M) {
    				count--;
    				N -= 4;
    				break;
    			}
    		}
            //가로로 이동한 횟수를 구했으니 세로로 이동할 휫수를 더해준다.
            //두 수중 어느 수가 큰 수 인지 않 수 없으니 빼주고 절대값으로 계산한다.
    		count += Math.abs(M - N);
    		System.out.println(count);
    	}
    
    }

    -결과-

     

    위가 좌표 / 아래가 먼저 푼 노가다식 코드


    아직 코딩 공부가 부족한 필자라 설명과 풀이 방법이 많이 미흡할 수 있다. 코딩 고수들은 보시고 문제점이 있다면 댓글로 말해주시면 감사한 마음으로 참고 수정 하겠다.

    댓글