ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준/BOJ] 1193번 : 분수찾기 (JAVA / 자바)
    백준 2022. 2. 14. 18:27

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

     

     

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

     

    1193번: 분수찾기

    첫째 줄에 X(1 ≤ X ≤ 10,000,000)가 주어진다.

    www.acmicpc.net


    - 문제 -

     

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

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

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

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

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

    https://comain.tistory.com/3

     

    (JAVA / 자바) Scanner 와 Bufferedreader

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

    comain.tistory.com

     

    풀이 방법

    두가지 방법으로 풀어 보았다.

    1. 패턴을 찾고 패턴으로 푸는 방법

    2. 반복문으로 입력값의 위치에 도달할때까지 돌리고, 해당 값을 출력하는 방법

     

    1. 패턴은 대각선 기준으로 위에서 아래로 내려갔다가 아래에서 위로 올라간다. 방향이 바뀔때마다 값이 하나 더 추가된다. 첫번째 대각선은 1개, 두번째 대각선은 2개, 세번째 대각선은 3개, ... 의 값을 가지게 되어있다. 이 패턴으로 보면 홀수 번째는 아래서 위로, 짝수번째는 위에서 아래로 내려간다는 것도 알 수 있다. 그렇다면 입력 값이 몇번째 대각선에 위치하고있는지를 구하고, 짝수일 경우와 홀수일 경우를 나눠서 경우에 맞는 값을 연산해서 출력해주면 된다.

    연산방식은 예를 들어 설명하겠다. 입력값이 7일 경우 이 7은 1 + 2 + 3 보다 크고 1 + 2 + 3 + 4 보다 작다. 그렇다면 7은 4번째 대각선에 존재한다는 것이다. 그렇다면 짝수이니 이 대각선 첫번째 값은 1 / 4가 될 것이다. 그렇다면 7번째 수는 (4 - (10 - 7)) / (4 + (((10 - 4) - 7) + 1))이 연산 값이 된다. 10은 1부터 4까지의 모든 합이고, 7은 입력값, 4는 대각선의 값이다. 연산 값은 1 / 4가 된다.

    만약 입력값이 8이라면 (4 - (10 - 8)) / (4 + (((10 - 4) - 8) + 1))이 될 것이고 값은 2 / 3이 된다.

    홀수라면 저 연산을 반대로 해주면 된다. 14일 경우 5번째 대각선이고, 1부터 5까지의 합은 15가 된다.

    연산은 (5 + (((15 - 5) - 14) + 1)) / (5 - (15 - 14)) 이 된다. 값은 2 / 4가 된다.

     

    2. A와 B라는 정수형 변수를 선언해준다. 값은 1을 저장한다. A와 B는 A/B이다.

    현재 구해지는 값이 어느 자리의 값인지 확인 할 i변수를 만들어 준다. 값은 1을 저장한다.

    A와 B가 둘다 1일때 B에 1을 더해주고, i에 1을 더해준다. 2번째 값이 1/2이라는 것이다.

    그 다음부턴 두가지의 조건문을 만들어주고 각각 반복문을 만들어준다.

    조건은 A가 1이고 B가 1이 아닐때, 다음 조건은 이것의 반대 A가 1이 아니고, B가 1일때이다.

    각각 첫 조건에는 반복문을 만들어주고, A에 1을 더해주고, B에는 1을 빼준다. 그럴때마다 i에도 1을 더해준다. i가 입력값과 같아지면 반복문을 종료한다. B가 1이 되어도 반복문을 종료한다. 조건문이 끝나기 전에 반복문이 끝나면 A에 1을 더해주고, i에도 1을 더해준다.(B에 더해주는 이유는 1/2에서 2/1이 되고, 다음 값은 3/1이기 때문이다.)

    다음 조건은 반대로 해주면 된다.

     

    코드로 보자.


    -풀이-

     

    1번 방법

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		int X = Integer.parseInt(br.readLine());
    		int i = 0;
    		int val = 0;
    		while(val < X) {
    			i++;
    			val += i;
    		}
    		
    		if(i % 2 == 0) {
    			System.out.println((i - (val - X)) + "/" + (i + (((val - i) - X) + 1)));
    		}else {
    			System.out.println((i + (((val - i) - X) + 1)) + "/" + (i - (val - X)));
    		}
    	}
    
    }

    2번 방법

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		int X = Integer.parseInt(br.readLine());
    		int A = 1;
    		int B = 1;
    		int i = 1;
    		
    		while(true) {
    			if(X == i || X == 1) break;
    			
    			if(A == 1 && B == 1) {B++; i++;}
    			
    			if(A == 1 && X != i) {
    				while(true) {
    					A++;
    					B--;
    					
    					i++;
    					
    					if(B == 1 || X == i) break;
    				}
    				if(B == 1 && X != i) {
    					A++;
    					i++;
    				}
    			}else if(A != 1 && X != i) {
    				while(true) {
    					A --;
    					B ++;
    					
    					i++;
    					
    					if(A == 1 || X == i) break;
    				}
    				if(A == 1 && X != i) {
    					B++;
    					i++;
    				}
    			}
    		}
    		System.out.println(A + "/" + B);
    	}
    
    }

    -결과-

     

    순서대로 1번방법, 2번 방법이다.

    코드의 간결함으로보나 시간으로보나 1번 방법이 더 좋아보이긴 한다. 하지만 그냥 문제와 코드만 봤을때는 2번 방법이 좀 더 이해하기 쉬울 것 같다.


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

    댓글