1193번 - 분수찾기
1. 문제
무한히 큰 배열에 다음과 같이 분수들이 적혀있다.
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 → 2/1 → 3/1 → 2/2 → … 과 같은 지그재그 순서로 차례대로 1번, 2번, 3번, 4번, 5번, … 분수라고 하자.
X가 주어졌을 때, X번째 분수를 구하는 프로그램을 작성하시오.
- Input
첫째 줄에 X(1 ≤ X ≤ 10,000,000)가 주어진다.
- Output
첫째 줄에 분수를 출력한다.
2. 사용 알고리즘
- 수학 (Math)
3. 풀이
해당 풀이는 가능한 한 코드의 길이를 줄이고자 하는 숏코딩 방식으로 구현되었다.
3.1. 수 나열
입력값 xx 와 이에 대한 출력값을 나열하면 다음과 같다.
1 - 1/1 2 - 1/2 3 - 2/1 4 - 3/1
5 - 2/2 6 - 1/3 7 - 1/4 8 - 2/3
9 - 3/2 10 - 4/1 11 - 5/1 12 - 4/2
13 - 3/3 14 - 2/4 15 - 1/5 16 - 1/6
⋮
3.2. 규칙 찾기
다음은 위에 나열된 분수를 분자와 분모 부분으로 구분하여 나타낸 표이다.
xx | 분자 | 분모 |
---|---|---|
11 | 11 | 11 |
22 | 11 | 22 |
33 | 22 | 11 |
44 | 33 | 11 |
55 | 22 | 22 |
66 | 11 | 33 |
77 | 11 | 44 |
88 | 22 | 33 |
99 | 33 | 22 |
1010 | 44 | 11 |
1111 | 55 | 11 |
1212 | 44 | 22 |
⋮ | ⋮ | ⋮ |
위 표에서 규칙성 있게 반복되는 구간별로 색상을 구분해 놓았다.
xx 에 대한 분자 결과값의 함수를 n(x)n(x), 분모 결과값의 함수를 d(x)d(x) 라고 두고 이 두 함수를 구해보자.
3.3. 보조함수 f(x)f(x)
xx | n(x)n(x) | d(x)d(x) | f(x)f(x) |
---|---|---|---|
11 | 11 | 11 | 11 |
22 | 11 | 22 | 22 |
33 | 22 | 11 | 22 |
44 | 33 | 11 | 33 |
55 | 22 | 22 | 33 |
66 | 11 | 33 | 33 |
77 | 11 | 44 | 44 |
88 | 22 | 33 | 44 |
99 | 33 | 22 | 44 |
1010 | 44 | 11 | 44 |
1111 | 55 | 11 | 55 |
1212 | 44 | 22 | 55 |
⋮ | ⋮ | ⋮ | ⋮ |
위 표에 표시된 값을 도출하는 함수 f(x)f(x) 를 정의한다.
3.4. 보조보조함수 g(x)g(x)
함수 f(x)f(x) 는 불연속함수 이므로, 이 함수를 도출가능한 연속함수 g(x)g(x) 함수를 우선으로 찾아야 한다.
위 표에서 함수 f(x)f(x) 의 함숫값 중 같은 함숫값에 대한 xx 의 최솟값만을 취하여 다시 표를 재작성하면 다음과 같다.
xx | f(x)f(x) | g(x)g(x) |
---|---|---|
11 | 11 | 11 |
22 | 22 | 22 |
44 | 33 | 33 |
77 | 44 | 44 |
1111 | 55 | 55 |
⋮ | ⋮ | ⋮ |
위 점들을 지나면서 연속함수인 g(x)g(x) 를 구해야 한다.
3.5. 함수 g(x)g(x) 찾기
위 표는 다음과 같이 일반화 할 수 있다.
xx | ΔxΔx | g(x)g(x) |
---|---|---|
11 | 11 | |
22 | 11 | 22 |
44 | 22 | 33 |
77 | 33 | 44 |
1111 | 44 | 55 |
⋮ | ⋮ | ⋮ |
g−1(y)g−1(y) | y−1y−1 | yy |
g−1(y)=1+y−1∑i=1i =1+y(y−1)2 =12y2−12y+1 =18(2x−1)2+78g−1(y)=1+y−1∑i=1i =1+y(y−1)2 =12y2−12y+1 =18(2x−1)2+78
따라서 함수 g(x)g(x) 는 다음과 같다.
g(x)=√8x−7+12g(x)=√8x−7+12
3.6. 숏코딩
더 효과적인 숏코딩을 위해 발악해보자.
3.6.1. 함수 h(x)h(x) 찾기 (g(x)g(x) 의 평행이동 함수)
좀 더 단순화된 함수를 찾기 위해 g(x)g(x) 를 평행이동 하고자 한다.
제곱근 내부의 식을 간소화 하기 위해 xx 축 방향으로 −78−78 만큼 평행이동한 함수 h(x)h(x) 는 다음과 같다.
h(x)=g(x+78)=√8(x+78)−7+12 =√8x+12=√2x+12h(x)=g(x+78)=√8(x+78)−7+12 =√8x+12=√2x+12
xx | g(x)g(x) | h(x)h(x) | floor(h(x))floor(h(x)) |
---|---|---|---|
11 | 11 | 1.911.91 | 11 |
22 | 22 | 2.502.50 | 22 |
33 | 2.562.56 | 2.952.95 | 22 |
44 | 33 | 3.333.33 | 33 |
55 | 3.373.37 | 3.663.66 | 33 |
66 | 3.703.70 | 3.963.96 | 33 |
77 | 44 | 4.244.24 | 44 |
88 | 4.274.27 | 4.504.50 | 44 |
99 | 4.534.53 | 4.744.74 | 44 |
1010 | 4.774.77 | 4.974.97 | 44 |
1111 | 55 | 5.195.19 | 55 |
1212 | 5.225.22 | 5.405.40 | 55 |
⋮ | ⋮ | ⋮ | ⋮ |
위 표와 같이
⌊g(x)⌋=⌊h(x)⌋⌊g(x)⌋=⌊h(x)⌋
를 만족함을 알 수 있다.
따라서 함수 f(x)f(x) 는 최종적으로 다음과 같다.
f(x)=⌊h(x)⌋=⌊√2x+12⌋=⌊√2x⌉f(x)=⌊h(x)⌋=⌊√2x+12⌋=⌊√2x⌉
⌊x+12⌋=⌊x⌉⌊x+12⌋=⌊x⌉
더 짧은 코드를 위해 위의 개념을 사용하였다.
3.7. 함수 n(x)n(x), d(x)d(x)
함수 f(x)f(x) 를 통해 함수 n(x)n(x), d(x)d(x) 를 구할 수 있다.
임의의 변수 aa, tt, bb 에 대해 다음과 같이 정의한다.
{a=f(x)t=∑an=1(n−1)b=x−t
이를 아래 표와 같이 나타낼 수 있다.
x | a | t | b | a−b+1 |
---|---|---|---|---|
1 | 1 | 0 | 1 | 1 |
2 | 2 | 1 | 1 | 2 |
3 | 2 | 1 | 2 | 1 |
4 | 3 | 3 | 1 | 3 |
5 | 3 | 3 | 2 | 2 |
6 | 3 | 3 | 3 | 1 |
7 | 4 | 6 | 1 | 4 |
8 | 4 | 6 | 2 | 3 |
9 | 4 | 6 | 3 | 2 |
10 | 4 | 6 | 4 | 1 |
11 | 5 | 10 | 1 | 5 |
12 | 5 | 10 | 2 | 4 |
⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
따라서 함수 n(x), d(x) 는 다음과 같다.
a=⌊√2x⌉
b=x−a∑n=1n(n−1)2
n(x)={b,if a % 2=0a−b+1,if a % 2=1
d(x)={a−b+1,if a % 2=0b,if a % 2=1
4. 제출 코드
위 알고리즘으로 코드를 작성하면 다음과 같다.
맞았습니다!!
n=int(input())*2;a=round(n**.5);b=(n-a**2+a)/2;print('%d/%d'%(a-b+1,b)[::a%2*2-1])
'Computer Science > Baekjoon' 카테고리의 다른 글
[Baekjoon] 10101번 삼각형 외우기 B4 <Short> (1) | 2024.01.20 |
---|---|
[Baekjoon] 1068번 트리 G5 (0) | 2024.01.15 |
[Baekjoon] 2839번 설탕 배달 B1 <Short> (0) | 2023.11.12 |
[Baekjoon] 2292번 벌집 B2 <Short> (0) | 2023.10.22 |
[Baekjoon] 2096번 내려가기 G5 (0) | 2023.09.23 |