728x90
문제
무한히 큰 배열에 다음과 같이 분수들이 적혀있다.
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)가 주어진다.
풀이
아이디어
- 대각선 라인수와 칸이 동일하다.
(ex. 1 번째 라인, 칸 1개. 2 번째 라인, 칸 2개) - 지그재그 순서로 진행하며, 라인의 끝 점까지의 칸 수를 End 로 둔다.
(End = {1, 3, 6, 10, 15, ... } ) - 내가 찾고자 하는 번째 수는 이미 지나친 끝점을 제외하고, 찾고자 하는 라인에서 몇칸 갈지만 알면 찾을 수 있다.
- 각 라인의 분수는 분자와 분모값의 합이 동일하며, 합은 (라인수 + 1) 이다. 따라서 [분자값 + 분모값 = 라인수 + 1]
(ex. 3번째 라인 [분자값 + 분모값 = 4] , [라인수 + 1 = 4])
즉, 분자와 분모값은 합을 나눠가진다. 분자가 커지는 만큼 합에서 가져가고, 분모는 합에서 남은 걸 가진다. - 라인수가 홀수인 경우,
분모값은 1부터 1씩 커지므로, 해당 라인에서 진행할 칸수가 분모값이 된다.
분자값은 합에서 분모값 뺀 값, (라인수 + 1) - 분모값 이다.
라인수가 짝수인 경우는 분모,분자 값을 반대로 가져오면 구할 수 있다.

코드
x = int(input())
#라인수와 끝점 구하기
line = 0
end = 0
while x:
line += 1
end += line
if x - end <=0:
end -= line
break
#끝점 제외 후 진행할 수 구하기
diff = x - end
#홀수인 경우 분모에 진행할 수, 분자에 합에서 분모 제외한 수 저장하기
#짝수인 경우는 분자, 분모를 반대 방법으로 저장
if line % 2:
denomi = diff
numer = line + 1 - denomi
else:
numer = diff
denomi = line + 1 - numer
print("{}/{}".format(numer,denomi))
검토
처음 규칙과 해법을 찾지 못해 한참을 헤맸다.
홀,짝 라인의 규칙을 찾지 못한 것이 큰 패착이다...
분자와 분모값을 각각 나열해 봤을 때, 특정 주기가 있다는 것을 안 나머지...
그 주기들을 나열한 수열이 등차수열이라 등차수열 합으로 끝점을 잡아 찾았다.
끝점 이후 얼만큼 진행할지는 주기에 해당하는 수열의 중간 값에서 떨어진 만큼을 통해 구했다.

아주 복잡하고도 비효율적인 방법으로 풀었지만 뿌듯했다 ^^
뻘짓을 기념하며 저세상 코드는 박제해 둔다.
x = int(input())
import math
if x == 1:
numerator = 1
denominator = 1
elif x == 2:
numerator = 1
denominator = 2
elif x == 3:
numerator = 2
denominator = 1
else:
#분자 건너뛸 수
for i in range(x):
if x - (2 * (i ** 2) - i) < 0:
break
numerMaxIdx = i - 1
#분자 진행할 수
numerCnt = x - (2 * (numerMaxIdx ** 2) - numerMaxIdx)
if numerCnt == 0:
numerCnt = 1
#분자 반복 주기 수
numerFrequency = 1 + (4 * numerMaxIdx)
#분자 중간 값
numerMiddle = math.ceil(numerFrequency / 2)
#분자
numerator = numerMiddle - abs(numerMiddle - numerCnt)
#분모 건너뛸 수
for i in range(x):
if x - (2 * (i ** 2) + i) < 0:
break
denomiMaxIdx = i - 1
#분모 진행할 수
denomiCnt = x - (2 * (denomiMaxIdx ** 2) + denomiMaxIdx)
if denomiCnt == 0:
denomiCnt = 1
#분모 반복 주기 수
denomiFrequency = 3 + (4 * denomiMaxIdx)
#분모 중간 값
denomiMiddle = math.ceil(denomiFrequency / 2)
#분모
denominator = denomiMiddle - abs(denomiMiddle - denomiCnt)
print("{}/{}".format(numerator,denominator))
'프로그래밍 > 코딩 문제 풀이' 카테고리의 다른 글
[백준] 단계별 문제풀이 #1000 - A+B (0) | 2024.07.16 |
---|---|
[백준] 단계별 문제풀이 #2557 - Hello World (0) | 2024.07.16 |
[백준] 단계별 문제풀이 #1712 - 손익분기점 (0) | 2024.07.16 |
[백준] 단계별 문제풀이 #1316 - 그룹 단어 체커 (0) | 2024.07.16 |
[백준] 단계별 문제풀이 #1157 - 단어 공부 (0) | 2024.07.16 |