본문 바로가기
Problem Solving/Baekjoon Online Judge

[BOJ #13417] 카드 문자열

by DeveloperHan 2020. 7. 25.

BOJ #13417, 카드 문자열 문제입니다.

처음에 C로 짜다가 입력 버퍼 관련 문제가 발생해서 한참 헤맸습니다만 Python으로 짜니까 바로 해결했습니다. 입력 버퍼 비우는 테크닉을 알고 있었는데 왜인지 잘 기억이 안 났었네요. 그리고 아직도 왜 안 되는지 모르겠습니다. 구글링도 열심히 하면서 해결하려고 해 보았으나 나중에 다시 시도해보기로 했습니다.

 

이 문제의 예제에서는 너무나 쉬운 testcase만을 제시하기 때문에, 혼자서 여러 가지 testcase를 만들어서 시험해봐야 합니다. 그리고 bit mask를 이용한 brute force도 문제의 입력 조건 상 시간이 부족하기 때문에 불가능하며 따라서 연역적인 과정을 통해 답을 도출할 수 있어야 합니다. (brute force의 범위를 좁히는 것이 권장되는 풀이일 수도 있겠습니다만 저는 연역적으로 풀었습니다.)

 

대부분의 프로그래밍 언어들에서는 ascii code 기준으로 문자(또는 문자열)의 순서를 판단하므로 이 문제는 숫자 정렬 문제와 동일하게 생각할 수 있습니다.

 

저는 제가 만든 여러 가지 testcase들을 탐구해 보았고, greedy algorithm을 적용해서 풀 수 있겠다는 결론에 도달했습니다. 저는 greedy algorithm을 적용하기 위해 '최소 문자'를 저장했습니다. 이 '최소 문자'를 통해 문자를 왼쪽에 붙였을 때와 오른쪽에 붙였을 때 중 어느 쪽이 사전 순으로 더 빠른지 판단할 수 있게 됩니다.

 

예를 들어 4 2 3 1 5의 입력이 들어왔다고 합시다. 4로 시작해서 2 4의 상태가 될 것입니다. 여기서 3의 위치를 선택해야 하는데, 만약 왼쪽에 붙인다면 3 2 4가 되어 기존보다 사전에서 느린 순서가 됩니다. 물론 이 다음의 1을 왼쪽에 붙이면 1 3 2 4가 되어 사전에서 빠른 순서가 되긴 합니다만, 그럴 바에야 3을 뒤에 붙이고 1을 왼쪽에 붙여 1 2 4 3으로 만드는 것이 사전에서 더 빠른 순서를 차지할 수 있습니다. 따라서, 우리는 '최소 문자'보다 더 빠른 문자만을(정확히는 더 빠르거나 같은 문자만을 - 왜냐하면 '최소 문자'를 중첩하는 것이 사전에서 빠른 순서가 되는 데에 유리하기 때문입니다.) 왼쪽에 붙이고 그 이외는 뒤에 붙여야 한다는 것입니다.

 

코드 첨부합니다. 다른 분들의 메모리나 시간 경과를 봤을 때 추후에 더 수정해 볼 예정입니다.

더보기
T = int(input(''))

for i in range(T):
    N = int(input(''))
    card_list = input('').split()

    min_card = card_list[0]
    res_list = [card_list[0]]

    for j in range(1, N):
        if min_card >= card_list[j]:
            min_card = card_list[j]
            res_list.insert(0, card_list[j])
        else:
            res_list.append(card_list[j])

    for j in range(N):
        print(res_list[j], end='')
    print()

'Problem Solving > Baekjoon Online Judge' 카테고리의 다른 글

[BOJ #1449] 수리공 항승  (0) 2020.07.29
[BOJ #10816] 숫자 카드 2  (0) 2020.07.27
[BOJ #11659] 구간 합 구하기 4  (0) 2020.07.19
[BOJ #11728] 배열 합치기  (0) 2020.07.18
[BOJ #2231] 분해합  (0) 2020.07.15

댓글