Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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
Archives
Today
Total
관리 메뉴

개발하지연

[백준 21314번] 민겸 수 (python) 본문

알고리즘

[백준 21314번] 민겸 수 (python)

JeongJiyeon 2021. 7. 16. 19:14

문제

민겸이는 로마 숫자를 보고 굉장히 흥미롭다고 생각했다. 그래서 민겸이는 새로운 수 체계인 민겸 수를 창조했다.

민겸 숫자는 0 이상의 정수 N에 대해 10N 또는 5 × 10N 꼴의 십진수를 대문자 M과 K로 이루어진 문자열로 표기한다. 10N 꼴의 십진수는 N + 1개의 M으로, 5 × 10N 꼴의 십진수는 N개의 M 뒤에 1개의 K를 이어붙인 문자열로 나타낸다. 즉, 아래 표처럼 나타낼 수 있다.

변환 전 변환 후
1 M
5 K
10 MM
50 MK
100 MMM
500 MMK
1000 MMMM
5000 MMMK
... ...

민겸 수는 한 개 이상의 민겸 숫자를 이어붙여 만든다. 예를 들어, 민겸 수 MKKMMK는 MK, K, MMK의 세 민겸 숫자를 이어붙여 만들 수 있다.

민겸 수를 십진수로 변환할 때는, 1개 이상의 민겸 숫자로 문자열을 분리한 뒤, 각각의 민겸 숫자를 십진수로 변환해서 순서대로 이어붙이면 된다. 민겸 숫자를 십진수로 변환하는 것은 십진수를 민겸 숫자로 변환하는 과정을 거꾸로 하면 된다. 예를 들어, 민겸 수 MKKMMK는 아래 그림과 같이 여러 가지 십진수로 변환할 수 있다.

민겸이는 위와 같이 하나의 민겸 수가 다양한 십진수로 변환될 수 있다는 사실을 알았다. 문득 민겸이는 변환될 수 있는 십진수 중 가장 큰 값과 가장 작은 값이 궁금해졌다. 민겸이를 위해 하나의 민겸 수가 십진수로 변환되었을 때 가질 수 있는 최댓값과 최솟값을 구해주자.

 

기록

(greedy 6일차) 구현할 수 있는 방법이 많이 생각나서 코드 가독성 생각하면서 구현했다.

 

코드

mg = input()

mg_max = []
mg_min = []
for mword in mg.split('K'):
    if mword:
        mg_min.append(str(10**(len(mword)-1)))
        mg_max.append(str(5*10**(len(mword))))
    else :
        mg_min.append('')
        mg_max.append(str(5))

print(''.join(mg_max[:-1])+'1'*(len(mg_max[-1])-1))
print('5'.join(mg_min))

최댓값은 다음과 같이 우선순위를 세웠다.

1. 5가 최대한 앞으로 오도록 K를 포함한 단위로 나누기

2. K를 포함할 수 없다면 M을 한 개씩만 묶어 0이 안 생기게 하기

따라서 K로 구분한 단위마다 5*10의 N제곱으로 변환하고(1), 마지막 단위는 '1'*N으로 변환했다.(2)

 

최솟값은 다음과 같이 우선순위를 세웠다.

1. 5가 최대한 뒤로 갈 수 있도록 K를 포함하지 않기

2. 0이 많아지도록 M끼리 최대한 묶기

따라서 K로 구분한 단위마다 10의 N-1제곱으로 변환하고(2), 5를 K자리에 넣었다.(1)

Comments