[BOJ] 10610

Posted by RoadtoS7 on January 07, 2020 · 2 mins read

문제

어느 날, 미르코는 우연히 길거리에서 양수 N을 보았다. 미르코는 30이란 수를 존경하기 때문에, 그는 길거리에서 찾은 수에 포함된 숫자들을 섞어 30의 배수가 되는 가장 큰 수를 만들고 싶어한다. 미르코를 도와 그가 만들고 싶어하는 수를 계산하는 프로그램을 작성하라.

풀이 과정

  • 30의 배수는 3의 배수이면서 10의 배수이다. 즉, 3과 10의 공배수이다.
  • 그렇기 때문에 우선 10의 배수이려면은 양수 N을 이루는 각 숫자 중 0이 포함되어야한다.
  • 그리고 3의 배수이기 때문에 각 자리 수의 합이 3의 배수여야한다.
  • 이 두가지를 이용하여 30의 배수인지를 검증하고, 양수 N의 각 자리수를 이용하여 가장 큰 수를 만들기 위해서는 양수 N을 이루는 수 중에서 가장 큰 수가 가장 높은 자리에 위치하면 된다.
  • 예를 들어서, N이 102인 경우 N을 이루는 수 중에서 가장 큰 수인 2가 100의 자리에 위치하고 그 다음으로 큰 수인 1이 10의 자리에 위치한다면, 1,0,2를 이용하여 가장 큰 수를 만들 수 있다.
  • 이를 볼 때 30의 배수이면서 가장 큰수는 1의 자리에 0이 위치할 수 밖에 없다.

앞서 말한 것들을 정리해 본다면 N에 포함된 숫자들 중 30의 배수가 되는 가장 큰 수의 조건은 다음과 같다. 1) 0이 존재한다. 2) 0이 1의 자리에 존재한다. 3) 각 자리수의 합(N에 포함된 수의 합)이 3의 배수이다.

num = str(input()) # 숫자 N을 담기위한 변수 num

numL = list() # N이 포함하는 수를 담기 위한 리스트인 numL

for i in range(len(num)): # 입력받은 숫자 N을 이루는 각각의 수를 리스트의 요소로서 numL에 저장한다.
    numL.append(int(num[i]))
    
numL.sort(reverse = True) # numL을 인덱스 0인 숫자부터 출력했을 때 가장 큰 수 부터 출력되도록 하기 위해서 내림차순으로 정렬한다.


# 0이 가장 작은 수 이므로, 내림차순으로 정렬했을 때 리스트의 가장 끝에 위치한다. 따라서 리스트의 가장끝에 0이 있는지를 검사하여 10의 배수인지 판단한다.
# 0이 존재하지 않는다면 10의 배수가 아니므로 -1을 출력한다.
if numL[len(numL) - 1] != 0 : 
    print(-1)
else:

# 10의 배수가 맞다면 각자리 수를 더하여 3의 배수인지 판단한다.
    sum = 0
    for i in range(len(numL) - 1):
        sum+=numL[i]

    if sum % 3 == 0:
# 10의 배수이면서 3의 배수인 경우라면 즉, 30의 배수라면 리스트를 인덱스 0인 자리부터 차례대로 출력한다.
        print(''.join(map(str, numL)))
    else: 
# 10의 배수이지만 3의 배수가 아닌 경우에는 -1을 출력한다.
        print(-1)

새롭게 알게된 점

  1. 처음에는 결과로 나타나는 수를 리스트로부터 만들기 위해 제곱계산을 사용했었는데 ‘시간초과’라는 결과가 나왔다. ‘시간초과’에 대한 이유가 제곱계산인지는 정확히 모르겠지만 그래도 사용할 때마다 지켜봐야할 것같다.
  2. 리스트.sort(reverse=True)를 하면 리스트를 내림차순으로 정렬할 수 있다.
  3. print(‘‘.join(map(str, numL)))을 하면 numL의 요소들의 타입이 현재 int 인데, sting형으로 형변환하여 ‘‘을 구분자로 하여 이어븥인 후, 출력하는 것이다. 숫자형 리스트를 10진수 형태로 출력할 때 유용했다.