링크: https://www.acmicpc.net/problem/1193
문제
무한히 큰 배열에 다음과 같이 분수들이 적혀있다.
| 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번째 분수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 X(1 ≤ X ≤ 10,000,000)가 주어진다.
출력
첫째 줄에 분수를 출력한다.
제한시간
0.5 초 (추가 시간 없음)
첫번째 시도
이 문제를 처음 접했을 때는 감을 못 잡아서, 직관적으로 떠오른 대로 코드를 작성했다.
X = int(input())
a = b = 1
is_turn = True
is_up = True
for _ in range(1, X):
if a == 1 and is_turn:
b += 1
is_up = False
is_turn = False
elif b == 1 and is_turn:
a += 1
is_up = True
is_turn = False
elif is_up:
a -= 1
b += 1
if a == 1: is_turn = True
else:
a += 1
b -= 1
if b == 1: is_turn = True
print(f"{a}/{b}")
is_turn으로 직선 이동을, is_up으로 대각선을 위로 올라갈지 아니면 아래로 내려갈지를 직접 구현했다.
Python3에선 TLE가 났고, PyPy3에선 AC가 나왔다.
하지만 이게 정해는 아닌 것 같았다.
왜냐하면 수학 태그가 붙어 있었지만, 정작 수학은 하나도 쓰지 않았기 때문이다.
두번째 시도
그래서 몇 번째 대각선에 속하는지만 판단하면 문제를 쉽게 풀 수 있을 것 같았다.
여기서 대각선은 오른쪽 위 방향을 기준으로 한다.
이 대각선 위에 있는 원소들은 모두 분자와 분모의 합이 일정하다.
대각선 번호는 왼쪽 위부터 1로 시작하며, 분자와 분모의 합은 항상 대각선 번호 + 1이 된다.
X = int(input())
item_count = line_number = line_sum = 0
while item_count + line_number < X:
item_count += line_number
line_number += 1
line_sum = line_number + 1
if line_number % 2 == 0:
a = X - item_count
b = line_sum - a
else:
b = X - item_count
a = line_sum - b
print(f"{a}/{b}")
결국 코드가 훨씬 깔끔해졌고, Python3에서도 AC받을 수 있었다!
'알고리즘 > PS' 카테고리의 다른 글
| [BOJ] 1759번 암호 만들기 (0) | 2025.12.21 |
|---|---|
| [BOJ] 9019번 DSLR (0) | 2025.11.20 |
| [BOJ] 17427번 약수의 합2 (0) | 2025.08.17 |
| [BOJ] 24313번 알고리즘 수업 - 점근적 표기 1 (0) | 2025.07.24 |
| [BOJ] 10464번 XOR (0) | 2025.06.25 |