[백준] 10816번 - 숫자 카드 2 | 파이썬

SangJin Ham·2023년 6월 21일
0

백준

목록 보기
12/51
post-thumbnail

10816번 - 숫자 카드 2


문제

숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 몇 개 가지고 있는지 구하는 프로그램을 작성하시오.


입력

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.

셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 몇 개 가지고 있는 숫자 카드인지 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다. 이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.


출력

첫째 줄에 입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 몇 개 가지고 있는지를 공백으로 구분해 출력한다.


예제 입력 1

10
6 3 2 10 10 10 -10 -10 7 3
8
10 9 -5 2 3 4 5 -10

예제 출력 1

3 0 0 1 2 0 0 2

첫 번째 코드

import sys

N = int(sys.stdin.readline().strip())
N_s = list(map(int, sys.stdin.readline().strip().split()))

M = int(sys.stdin.readline().strip())
M_s = list(map(int, sys.stdin.readline().strip().split()))

result = []

for m in M_s:
  result.append(N_s.count(m))

print(*result)

첫 번째 코드 풀이

시간초과

첫 번째 코드같은 경우엔 시간복잡도를 고려하지 않고 작성한 코드이다.
단순히 N_sm이 몇개 들어있는지 listcount 연산자를 이용한 출력이다.


두 번째 코드

import sys

N = int(sys.stdin.readline().strip())
N_s = sorted(list(map(int, sys.stdin.readline().strip().split())))
M = int(sys.stdin.readline().strip())
M_s = list(map(int, sys.stdin.readline().strip().split()))

n_dic = {}
for n in N_s:
  if n in n_dic:
    n_dic[n] += 1
  else:
    n_dic[n] = 1

def binary(m, N_s, start, end):
    if start > end:
        return 0
    mid = (start + end)//2
    if m == N_s[mid]:
        return n_dic[m]
    elif m < N_s[mid]:
        return binary(m, N_s, start, mid-1)
    else:
        return binary(m, N_s, mid+1, end)



for m in M_s:
  print(binary(m, N_s, 0, len(N_s)-1), end=' ')

두 번째 코드 풀이

메모리 : 114628KB
시간 : 2780ms

두 번째 코드같은 경우엔 이분탐색사전형을 이용한 풀이이다.

먼저 N_s를 입력받을 때 이분탐색을 하기위해 정렬된 리스트로 저장한다.
그 후 N_s의 원소들의 개수를 구해주는 n_dic 사전형을 생성한다.

그리고 이분탐색 binary 함수를 구현한다.

  • 검색할 정수 m, 검색할 리스트 N_s, 시작할 인덱스 start, 마지막 인덱스 end
  • 만약 mN_s\[mid(중간인덱스)]와 같다면 n_dic\[m] 출력 즉, N_s에서의 m의 개수를 출력해준다.
  • 크거나 작다면 그에 따라 인덱스를 정해 binary 함수를 재귀로 호출한다.
  • 그렇게 반복하다가 N_s에서 m값을 찾지 못하면 return 0한다.

세 번째 코드

import sys

N = int(sys.stdin.readline().strip())
N_s = list(map(int, sys.stdin.readline().strip().split()))
M = int(sys.stdin.readline().strip())
M_s = list(map(int, sys.stdin.readline().strip().split()))

n_dic = {}

for n in N_s:
  if n in n_dic:
    n_dic[n] += 1
  else:
    n_dic[n] = 1

for m in M_s:
  if m in n_dic:
    print(n_dic[m], end=' ')
  else:
     print(0, end=' ')

세 번째 코드 풀이

메모리 : 115648KB
시간 : 860ms

세 번째 코드같은 경우엔 사전형을 이용한 풀이이다.

먼저 N_s의 원소들의 개수를 구해주는 n_dic 사전형을 생성한다.

그 후 for문을 이용해 if m in n_dic 이라면 n_dic\[m]Value 값을 출력해주고 아니라면, 0을 출력한다.

이렇게 다양한 풀이방법이 있지만 이분탐색을 이용해 구현하는 방법을 안다면 사전형을 이용해 간단하게 구현해도 별문제 없지만, 모른다면 꼭 이분탐색을 이용해 구현해보고 다른 방법을 이용해 구현해보는 게 좋을 거 같다.

profile
끄적끄적

0개의 댓글