SWEA()/Intermediate_Learn

[SWEA]4834. 파이썬 SW문제해결 기본 - LIST 1 : 숫자 카드

코딩의행복 2021. 11. 1. 10:00

파이썬 SW문제해결 기본 - LIST 1

4834. 08 숫자카드(SW문제)


이미지를 클릭하시면 SW Expert Academy의 해당 강좌로 이동합니다

08. 숫자 카드

🎲문제 : 위 이미지를 클릭하여 SWEA 이동 -> 8차시 1일 차 - 숫자 카드


🥾문제 접근:

- 크기 10의 리스트를 생성하고, 카드에 해당하는 인덱스를 1씩 증가시킨 후 최댓값을 찾으면 될 것 같다. 최댓값이 2개 이상인 경우 큰 숫자를 출력한다.

    📍 max(iterable) : 반복 가능한 자료형을 입력받아 최댓값을 return 한다.

- 앞서 배운 List의 내장 함수 max()를 활용할 수 있다.

List란? - [SWEA]파이썬 SW문제해결 기본 - LIST 1 : 알고리즘, 리스트

 

[SWEA]파이썬 SW문제해결 기본 - LIST 1 : 알고리즘, 리스트

파이썬 SW문제해결 기본 - LIST 1 01 알고리즘 02 리스트 01. 알고리즘 ① 알고리즘 개요 ▣ 알고리즘이란? - 유한한 단계를 통해 문제를 해결하기 위한 절차나 방법 ▣ 알고리즘 표현법 - 슈도 코드 :

taewow.tistory.com


🎯 문제 해결:
(최종 코드는 제일 하단 참고)


첫 번째 시도 - ❌FAIL

T = int(input())
for test_case in range(1, T + 1):
    #1
    length = int(input())
    n = int(input())
    cards = [0 for i in range(10)]
    #2
    for i in range(length):
        cards[n%10] += 1
        n = int(n/10)    
    #3
    ans_count = max(cards)
    while (cards.count(ans_count) > 1):
        cards[cards.index(ans_count)] = 0
    #4
    ans = cards.index(ans_count)
    print(f"#{test_case} {ans} {ans_count}")

#1 양수의 개수 length를 input()을 통해 입력받았다. (5 ≤ length ≤ 100)

다음으로 주어지는 N개의 카드가 여백 없이 주어지므로 우선 통째로 입력받아 정수형으로 변환하였다.
('12345'를 1, 2, 3, 4, 5가 아닌 1만 2천3백4십5(12345)로 받음)

각 카드의 개수를 카운팅 할 10 크기의 'cards' 배열을 선언 및 초기화하였다.

#2 입력받은 카드(n)를 10으로 나누어 가며 카드의 개수를 cards 배열에 +1씩 카운팅 했다.

#3 'cards'의 최댓값(가장 개수가 많은 카드)을 찾는다. 그다음으로 만약 가장 많은 카드가 동점(2 카드 이상)이라면, 숫자가 작은 카드의 개수를 '0개'로 만든다. 이 과정은 가장 많은 카드가 한 종류만 남을 때까지 반복된다.

사실 이 과정에서 그냥 뒤에서 찾으면 되는 것 아닌가? 하는 의문이 생길 것이다. 그렇다. 맞는 말이다. 다만 이 문제를 풀 당시의 나는 그 방법을 몰랐거나, 알더라도 구현을 못했거나 했던 것 같다...🙄

#4 가장 개수가 많은 카드를 출력한다.

이 코드의 결과는? - ❌FAIL


두 번째 시도 - ✅PASS

첫 번째 코드는 테스트 케이스는 훌륭히 통과하였으나, '제출'은 통과하지 못했다. 처음에는 원인을 파악하지 못하였으나 문제 조건에서 곧 원인을 파악할 수 있었다. 정수형으로 입력받는 '카드'의 길이는 5≤N≤100이다. 이는 정수의 길이가 최대 100... 다시 말해 10e+99까지 표현을 해야 한다. 아무리 파이썬의 정수형이 길이의 제한이 없다고 하지만... 이건 좀 아니다. 그래서 문자열로 받는 것으로 변경하였다.
물론 이렇게 입력이 길 경우 최선의 방법은 한 번에 한 글자씩 입력받아 연산하는 것이다. 그러나 C++와 달리 파이썬에는 이를 어떻게 하는지 잘 몰랐었다...🙄(지금 보니 부끄러운 점이 참 많은 코드이다.)

T = int(input())
for test_case in range(1, T + 1):
    length = int(input())
    #1
    n = input()
    cards = [0 for i in range(10)]
    
    for i in range(length):
        cards[int(n[i])] += 1
    
    ans_count = max(cards)
    #2
    for i in range(10):
        if cards[i] == ans_count:
            ans = i
    print(f"#{test_case} {ans} {ans_count}")

#1 입력을 받아 정수형으로 변환하던 이전 코드에서, 정수형으로 변환하지 않고 그대로(문자열) 받아 변수 'n'에 저장했다.

#2 이전 코드에서는 최댓값을 하나만 남기는 방식을 사용했었다. 그러나 이 방식은 연산도 입출력도 더 많이 발생하고 기껏 세어놓은 count 정보를 손실한다는 큰 단점이 있었다. 따라서 작은 카드에서 큰 카드로 가며 최댓값 카드를 갱신하는 방식으로 수정하였다. (물론 이것 또한 최선은 아니다. 이는 count 리스트 전체를 순회해야 하지만 뒤에서부터 찾을 경우 전체를 순회하지 않아도 된다.)

이 코드의 결과는? - ✅PASS