728x90
반응형

문제:

이제 10 살이 된 헨리(Henry)는 수학에 소질이 있다. 수학선생님인 아메스(Ahmes)는 오늘 헨리에게 분수에 대해 가르쳐줬고, 헨리는 분수를 이리저리 계산해보는 것이 너무 재미있었다. 그러던 중에 헨리는 1 보다 작은 분수를 여러 개의 서로 다른 단위분수의 합으로 표현할 수 있다는 것을 알아내었다. 여기서 단위분수란 분자가 1 인 분수를 말한다. 헨리는 여러 개의 분수에 대해 이를 시도해봤고, 시도해본 분수들은 모두 서로 다른 단위분수의 합으로 표현할 수 있었다. 예를 들어, 423 16+1138와 같이 두 개의 단위 분수의 합으로 나타낼 수 있다. 

헨리는 이런 발견을 선생님인 아메스에게 자랑스럽게 이야기했다. 아메스는 이를 듣고는 크게 기뻐하며 어린 제자를 칭찬했고, 이와 같이 하나의 분수를 서로 다른 단위분수의 합으로 표현한 것을 헨리식 표현법(Henry representation)이라고 이름 지었다. 즉, 분수 ab의 헨리식 표현법은 총합이 ab 와 같게 되는 서로 다른 단위분수의 나열이다. 헨리와 아메스는 헨리식 표현법에 대하여 더욱 연구하였고, 마침내 모든 1 보다 작은 분수는 헨리식 표현법이 가능함을 증명하였다. 또한 헨리식 표현법이 유일하지 않다는 것도 알 수 있었다. 예를 들면, 57=12+15+170=12+16+121=12+17+114 와 같이 여러 가지 다른 헨리식 표현법이 존재할 수 있다. 단, 정의에 의해, 헨리식 표현법에는 같은 단위분수가 두 개 이상 포함될 수 없으므로 23=13+13 는 헨리식 표현법이 아님을 유념해야 한다.

아메스와 헨리는 또한 주어진 분수의 헨리식 표현법을 구하는 간단한 방법도 고안해냈다. a<b인 양의 정수 a b로 이루어진 분수 ab가 주어질 때에, 먼저 1x1ab를 만족하는 가장 큰 단위 분수 1x1를 계산한다. 그런 다음 ab 에서 1x1를 뺀 나머지에 대하여 위의 과정을 반복한다. 즉, 1x2ab1x1를 만족하는 가장 큰 단위분수 1x2를 계산하고 뺀다. 이러한 과정을 나머지가 남지 않을 때까지 반복한다. 그러면 서로 다른 단위분수들 1x1,1x2,1x3,을 순서대로 얻게 되며 그들의 합은 정확히 ab와 같아진다. 아메스와 헨리는 이 알고리즘이 항상 종료하며 합이 ab가 되는 서로 다른 단위분수들, 즉 헨리식 표현법을 출력함을 증명하였다.

아메스와 헨리는 당신에게 그들의 알고리즘을 컴퓨터 프로그램으로 구현해줄 것을 부탁했다. 입력으로 주어지는 1 보다 작은 분수 ab 를 아메스와 헨리의 알고리즘을 수행하여 헨리식 표현법을 계산할 때에 마지막 단위 분수의 분모를 출력하는 프로그램을 작성하시오. 예를 들어. ab=57라면, 아메스와 헨리의 알고리즘은 57=12+15+170 을 출력하게 되므로 당신의 프로그램은 반드시 70 을 출력해야 한다.

입력:

입력 데이터는 표준입력을 사용한다. 입력은 T 개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 테스트 데이터의 개수 T 가 정수로 주어진다. 각 테스트 데이터는 한 줄로 구성되며, 여기에는 입력 분수 
ab를 의미하는 두 개의 정수 a b (1 ≤ a < b ≤ 10,000) 가 주어진다. 이때, a b는 서로소이며, 입력분수 ab 에 대해 아메스와 헨리의 알고리즘을 실행했을 때에 출력되는 단위 분수가 순서대로 1x1,1x2,1x3,,1xm 라면, bx1x2xm1<231 의 부등식을 만족한다고 가정할 수 있다.

출력:

출력은 표준출력을 사용한다. 각 테스트 데이터에 대해, 정확히 한 줄을 출력해야 하며 여기에는 정수 하나만을 출력한다. 이 정수는 아메스와 헨리의 알고리즘을 입력 분수 ab 에 대해 실행했을 때, 출력되는 헨리식 표현법의 마지막 단위분수의 분모와 같아야 한다.

풀이 방법:

가장 큰 1/x를 구하기 위해서는 원래 분수에서 분자를 1로 만들었을 때에 생기는 분모의 값을 올림해주면 된다. (분수의 경우에 분모가 작을수록 크다.)
따라서 (a/b-1/x1-1/x2- .... )의 분자가 1이 될 때까지 while로 반복하도록 한다. 또한 새 분수를 만들고 나서 약분하는 작업이 필요하므로 분수 계산을 도와주는 모듈인 fraction을 사용하도록 한다.


1
2
3
4
5
6
7
8
9
from fractions import Fraction
for i in range(int(input())):
    a,b=map(int,input().split())
    while(a!=1):
        c=b//a+1
        a=a*c-b
        b=b*c
        a,b=map(int,str(Fraction(a,b)).split('/'))
    print(b)
cs


728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]1015. 수열 정렬  (0) 2019.05.16
[BOJ]1547. 공  (0) 2019.05.15
[BOJ]3036. 링  (0) 2019.05.13
[BOJ]2591. 이항 쇼다운  (0) 2019.05.12
[BOJ]2407. 조합  (0) 2019.05.11
728x90
반응형

문제:

상근이는 창고에서 링 N개를 발견했다. 상근이는 각각의 링이 앞에 있는 링과 뒤에 있는 링과 접하도록 바닥에 내려놓았다. 

상근이는 첫 번째 링을 돌리기 시작했고, 나머지 링도 같이 돌아간다는 사실을 발견했다. 나머지 링은 첫 번째 링보다 빠르게 돌아가기도 했고, 느리게 돌아가기도 했다. 이렇게 링을 돌리다 보니 첫 번째 링을 한 바퀴 돌리면, 나머지 링은 몇 바퀴 도는지 궁금해졌다.

링의 반지름이 주어진다. 이때, 첫 번째 링을 한 바퀴 돌리면, 나머지 링은 몇 바퀴 돌아가는지 구하는 프로그램을 작성하시오,

입력:

첫째 줄에 링의 개수 N이 주어진다. (3<=N<=100)

다음 줄에는 링의 반지름이 상근이가 바닥에 놓은 순서대로 주어진다. 반지름은 1과 1000을 포함하는 사이의 자연수이다.

출력:

출력은 총 N-1 줄을 해야 한다. 첫 번째 링을 제외한 각각의 링에 대해서, 첫 번째 링을 한 바퀴 돌리면 그 링은 몇 바퀴 도는지 기약 분수 형태 A/B로 출력한다.

풀이 방법:

 모든 링은 첫 번째 링의 크기에 따라서 돌아가는 횟수가 정해지게 된다. 예제의 경우로 보면 첫 번째 링이 12이므로 두 번째 링은 12/3 인 4이고, 세 번째 링은 12/8=3/2, 마지막 링은 12/4 이므로 3이 되게 된다. 

python에서는 이러한 분수 약분 및 계산을 해주는 fraction이라는 모듈이 있다. 따라서 첫 번째 링을 기준으로 나머지 링에 대해 분수형태로 만들면 된다. 하지만 정수인 경우에도 분수 형태로 만들어 줘야 하는 작업이 필요하므로, 따로 분류해서 만들어주도록 한다.

1
2
3
4
5
6
7
8
9
from fractions import Fraction
a=int(input())
number=list(map(int,input().split()))
for i in range(1,len(number)):
    result=Fraction(number[0],number[i])
    if int(result)==result:
        print(str(result)+"/"+"1")
    else:
        print(str(result))
cs


728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]1547. 공  (0) 2019.05.15
[BOJ]10253. 헨리  (0) 2019.05.14
[BOJ]2591. 이항 쇼다운  (0) 2019.05.12
[BOJ]2407. 조합  (0) 2019.05.11
[BOJ]1676. 팩토리얼 0의 개수  (0) 2019.05.10

+ Recent posts