Home [백준] 1431 시리얼 번호(Python)
Post
Cancel

[백준] 1431 시리얼 번호(Python)

해당 게시글에서는 [백준] 1431 시리얼 번호 문제를 해설하고 Python을 이용하여 풀고자 한다.

🤔 접근법

1341번 문제는 정렬에 관한 문제이다.

애초에 문제에서 정렬이라고 밝히고 있기 때문에 정렬 문제라는 걸 아는 건 크게 어렵지 않을 것이다.

시리얼번호 A가 시리얼번호 B의 앞에 오는 조건은 다음과 같이 해석할 수 있다.

  • A와 B의 길이가 다르면, 짧은 것이 먼저 온다. 👉 문자열의 길이에 따라 정렬
  • 만약 서로 길이가 같다면, A의 모든 자리수의 합과 B의 모든 자리수의 합을 비교해서 작은 합을 가지는 것이 먼저온다. (숫자인 것만 더한다) 👉 각 자리 숫자의 모든 합에 따라 정렬
  • 만약 1,2번 둘 조건으로도 비교할 수 없으면, 사전순으로 비교한다. 숫자가 알파벳보다 사전순으로 작다. 👉 사전순 정렬(기본 sort 정렬)

따라서 람다함수를 통해 정렬의 우선 순위에 따라 인자를 잘 넘겨주면 될 것이라 생각했다.

하지만 첫 번째, 세 번째 조건은 len() 함수와 일반적인 sort를 쓰면 될 것이라 생각했지만, 두 번째 조건을 처리할 방법을 모르겠어서 다른 블로그를 참고했다.

💡 문제 풀이

이제 문제의 조건은 모두 파악했으므로 sort 함수와, 정렬의 조건이 되는 lambda 식을 잘 작성하면 된다.

첫 번째 조건은 len 함수를, 세 번째 조건은 원래 값을 lambda에 넘겨주면 되지만, 두 번째 조건을 바로 나타낼 수 있는 함수는 없다.

따라서 다음과 같이 string에서의 숫자 문자들의 합을 반환하는 함수를 정의했다.

1
2
3
4
5
6
def sum_digit(str):
    ans = 0
    for s in str:
        if s.isdigit():
            ans += int(s)
    return ans

모든 조건을 처리할 수 있게 됐으므로 이제 lambda 식을 작성하면 된다.

lambda를 통해 여러 조건에 따른 정렬을 할 때, 조건이 에 올수록 먼저 정렬된다는 것을 알아두자. 또 lambda에 넘겨준 매개변수의 값이 작을수록 앞에 위치한다.

우선순위가 큰 것이 앞에 와야하므로 첫 번째 조건인 string의 길이를 나타내는 len(x)를 맨 앞에, 두 번째 조건인 sum_digit(x)를 그 다음에, 사전순 정렬(일반 정렬)을 나타내는 x를 마지막에 작성했다.

1
sorted(num, key=lambda x:(len(x), sum_digit(x), x))

📂 Code

위 문제 풀이 방식을 통해 해당 문제를 풀어낸 필자의 코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
import sys
read = sys.stdin.readline

def sum_digit(str):
    ans = 0
    for s in str:
        if s.isdigit():
            ans += int(s)
    return ans

num = [read().strip() for _ in range(int(read().strip()))]
for n in sorted(num, key=lambda x:(len(x), sum_digit(x), x)):
    print(n)
This post is licensed under CC BY 4.0 by the author.

[JAVA] 클래스명과 파일명은 왜 같아야 하는가?

[백준] 2447 별 찍기 - 10(Python)