*백준-1193번(일반수학1-분수찾기)-층별 규칙 찾아내기

하스코딩·2025년 3월 23일

풀이

  • 이번에도 규칙 찾는데 해멨다. 수학 일반식을 도출하는 것이 예전부터 어려웠는데, 이런 수학 코딩문제를 풀 때 헤매게 되는 것 같다.
  1. 먼저 아래 사진처럼 그룹을 나눠주면 각 대각선 층의 개수는 1씩 증가하며, 대각선 블록 수가 짝수면 내려가고, 홀수면 올라간다.
    -이 대각선 블록 수 cnt를 기준으로 잡아 두 케이스로 나눌 수 있다.

  2. 가장 중요한 두번째 규칙으로는 한 대각선의 블록들은 분모 + 분자 = T로 모두 같다는 점이다.
    -여기서 T = cnt(현재대각선의 블록 수)+1이다.
    -이 T를 사용해서 분자, 분모를 구할 수 있다. cnt%2==1인 상황을 예로 설명해보겠다.
    -홀수이므로 분자가 큰수에서 시작, 분모는 작은수에서 시작한다.

  • 분모: (X번째 블록 - 누적 블럭 수) = 현재 대각선에서의 몇번째인지 번호
    ex) 5번째 분수: (5 - 3) = 2로 현재 대각선 중 2번째 값 출력

  • 분자: (전체T - 분모) = 분자 이므로 이 식을 구체화하면
    (현재대각선 수+1) - (X번째 - 누적블럭수) = 분자
    ex) 5번째: 3-(5-3)+1 = 2가 된다.

  1. 앞서 두 조건들을 사용해 코드를 작성해보면, 무한루프 속 if문에서 (대각선까지의 블록 누적 합 prev_cnt)와, (현재 대각선 블록 수 cnt를) 통해 X번째 블록이 속한 대각선을 찾는다.
    -그리고 그 대각선이 올라가는 방향인지 내려가는 방향인지를 대각선 블록 수 cnt의 홀,짝수 여부로 판단해 주었다.
import java.io.*;
import java.lang.*;


public class Main {

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));


        //X번째 분수 구하기
        int X = Integer.parseInt(br.readLine());

        //층마다 분모+분자=T라고 하면,
        //1층 2, 2층 3, 3층 4 ... 이다.

        //현재 대각선 개수는 1~n까지 1씩 증가함= 대각선수 홀수: 올라가는방향, 대각선수 짝수: 내려가는 방향
        int prev_cnt = 0;//직전 대각선 누적 합
        int cnt = 1;//현재 대각선 개수

        while(true){

            //이러면 X번째 블록이 현재 대각선 cnt에 존재하는 것
            if(X <= prev_cnt + cnt){

                //현재 대각선 개수 홀수면 올라가는 방향
                if(cnt%2==1){//분자가 큰 수로 시작
                    //분자: 현재대각선 수-(X번째-누적블럭수)+1, 블럭은 1부터 시작하므로 +1해줌
                    //ex) 5번째: 3-(5-3)+1 = 2로,
                    //큰수로 시작하므로 (현재대각선 최댓값)에서 (현재대각선에서의 번호+1)을 빼줌

                    //분모: X번째 - 누적 블럭수 = 현재 대각선에서의 번호
                    //ex) 5번째: 5-3 = 2로 현재 대각선 중 2번째 값 출력
                    System.out.println( (cnt - (X-prev_cnt-1)) + "/" + (X-prev_cnt) );
                    break;

                }
                //현재 대각선 개수가 짝수면 내려가는 방향
                else{//분모가 큰 수로 시작하므로 홀수일때와 반대로 출력
                    System.out.println( (X-prev_cnt) + "/" + (cnt - (X-prev_cnt-1)) );
                }   break;
            }
            else{
                prev_cnt += cnt;//현재 대각선도 누적 합에 포함 후
                cnt++;//다음 대각선 수로 1 증가
            }
        }
        br.close();
    }

}

0개의 댓글