본문 바로가기

[BAEKJOON] 1193번


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) {
        System.out.print(new Main().run());
    }
 
    public String run() {
        Scanner sc = new Scanner(System.in);
        int input = sc.nextInt();
        int count = 0;
        int numer = 1, denom = 1;
        String result = null;
        
        for(int i = 1; count < input; i++) {
 
            if(i%2 == 0) {
                numer = 1;
                denom = i;
                        
                for(int j = 1; j <= i; j++, numer++, denom--) {
                    count++;
                        
                    if(count >= input) {
                        break;
                    }
                }
            } else {
                numer = i;
                denom = 1;
                        
                for(int j = 1; j <= i; j++, numer--, denom++) {
                    count++;
                        
                    if(count >= input) {
                        break;
                    }
                }
            }
                    
        }
        
        sc.close();
        
        result = Integer.toString(numer) + "/" + Integer.toString(denom);
        
        return result;
    }
}
cs


 denom 은 분모를,  numer 는 분자를 나타낸다.

보기에 나온 순서대로 짝수일 때는 분자가 증가하고 분모가 감소한다.

홀수일 때는 그 반대로 움직인다.


썩 마음에 드는 코드가 아니라서 조금 찾아보니 다음과 같은 코드도 있었다.

(출처: https://codingplus.tistory.com/124


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
int main()
{
    int x, count = 0;
 
    scanf("%d"&n);
 
    while (x > 0)
    {
        ++count;
        x -= count;
    }
 
    if (count % 2 == 0) { printf("%d/%d", count + x, 1 - x); }
    else { printf("%d/%d"1 - x, count + x); }
 
    return 0;
}
cs


1/1

1/2

1/3

1/4

1/5

2/1

2/2

2/3

2/4


3/1

3/2

3/3



4/1

4/2




5/1



 

 


출처 블로그에는 다음과 같이 기술되어 있다.


1. 1씩 증가하는 등비 수열로 규칙을 이루고 있다. (1, 2, 3, 4, ..)

2. 입력 값의 수열이 얼마나 진행된 수인지 판별을 한다. 

   (얼마나 진행된 수열인지, 몇 번째의 자리인지 2가지를 도출할 수 있다.)

3. 짝수일 때와 홀수일 때는 출력 순서가 다르다는 것을 인지하고 출력을 유도한다.


2번의 자세한 과정이 궁금해 조금 생각해보니 어느 정도는 알 것 같았다.


문제에서 주어진 표를 대각선으로 보자.

그러면 홀수번째 대각선과 짝수번째 대각선으로 나눌 수 있다.

홀수번째 대각선에서는 왼쪽 위로 움직이며 분모가 증가하고 분자가 감소한다.

반대로 짝수번째 대각선에서는 오른쪽 아래로 움직이며 분모가 감소하고 분자가 증가한다.

또한 대각선의 길이는 등차수열을 이룬다.


따라서 입력받은  x 에서 1, 2, 3, 4,  를 빼준다. 그러면  x 는 0또는 음수가 된다.

만약에  x 가 8이라면,  x 에서 1~4의 합인 10을 뺀 상태에서 반복문을 탈출하게 된다.


이 때  x 는  -2 고  count 는  4 다. 현재  x 의 절댓값은 현재 위치(5/1)가 정답 위치에서 

얼마나 지났는지 나타낸다. 따라서  count + x 는 원래 있어야할 위치가 된다( x 는 항상 0 또는 음수이므로). 그리고 모든 분자, 분모는 1부터 시작하므로  -n 이 아닌  - n 이 분자 또는 분모가 된다. 


단, 이는  count 의 홀짝 여부에 따라 분모인지 분자인지가 결정된다.  count 가 짝수라면 현재 위치는 홀수번째 대각선이 된다. 이 경우  count + x 가 분자가 되고  1 - n 이 분모가 된다.

따라서 정답  2/3 이 출력된다. 홀수번째 대각선에서 움직이는 방향과 짝수번째 대각선에서 움직이는 방향이 서로 반대기 때문이다. 

먼저 1, 2, 3, 4, 의 위치는 대각선의 끝점이다. 그런데 이 위치는 분모와 분자 중 하나만 증가 또는 감소된 결과다. 따라서 홀수일 때와 짝수일 때의 분모/분자가 반대로 출력되어야 하는 것이다.

'Programming > Solutions' 카테고리의 다른 글

[Project Euler] Problem 012  (0) 2019.04.08
[Project Euler] Problem 011  (0) 2019.04.08
[Project Euler] Problem 010  (0) 2019.03.31
[Project Euler] Problem 009  (0) 2019.03.30
[BAEKJOON] 1011번  (0) 2019.03.26