Python/코딩테스트

[백준] 10816. 숫자 카드 2

edoyyoy 2023. 10. 9. 16:33

백준 10816. 숫자카드 2

 

10816번: 숫자 카드 2

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

www.acmicpc.net

 

실버 4

 

 

문제풀이 : 카운터 함수

from collections import Counter
import sys
input = sys.stdin.readline


n = int(input())
num = list(map(int, input().split()))
m = int(input())
chk = list(map(int, input().split()))
res = []

count = Counter(num)
num = set(num)

for c in chk:
    if c in num:
        res.append(count[c])
    else:
        res.append(0)

print(' '.join(map(str, res)))

 


< 풀이 : 이분탐색 (시간초과) >

import sys
input = sys.stdin.readline

n = int(input())
num = list(map(int, input().split()))   #숫자 카드의 수
m = int(input())
chk = list(map(int, input().split()))   #확인할 수
res = []    #답

num.sort()

for c in chk:
    s, e = 0, n-1
    cnt = 0
    while s <= e:
        mid = (s+e)//2
        
        #카드에 수가 존재하는 경우
        if num[mid] == c:
            cnt += 1
            
            #앞-뒤로 같은 수가 있는 경우 체크
            #앞의 수 체크
            for i in range(mid-1, -1, -1):
                if num[i] == c:
                    cnt += 1
                else:
                    break
                
            #뒤의 수 체크
            for j in range(mid+1, n):
                if num[j] == c:
                    cnt += 1
                else:
                    break
            
            #이분탐색 종료 (같은 수의 값 다 찾음)
            break
        
        # 주어진 수보다 작은 경우
        elif num[mid] < c:
            s = mid+1
        
        # 주어진 수보다 큰 경우
        else:
            e = mid-1
            
    
    res.append(str(cnt))

print(' '.join(res))

 

< 풀이 : 배열 >

from collections import Counter
import sys
input = sys.stdin.readline


n = int(input())
num = list(map(int, input().split()))
m = int(input())
chk = list(map(int, input().split()))
res = [0] * 20000001

for i in num:
    res[i+10000000] += 1

for j in chk:
    print(res[j+10000000], end=' ')

 

먼저 문제 아이디어로 이분탐색, 카운트 함수, 배열 이렇게 3가지 방법을 떠올렸다.

지금은 이분탐색을 공부하는 중이여서 이분 탐색으로 먼저 풀었다.

이분탐색으로 접근을 했을 때 찾은 수 앞 뒤로 카운팅을 해줬더니 시간초과가 났다..

일단 다른 방법도 되나 하고 카운트를 했을때 카운트는 성공했지만, 이분탐색은 아직도 잘 모르겠다.

다른 분들 풀이를 참고하니 딕셔너리에 존재하는지 여부를 이분탐색으로 푸셨던데 굳이..? 알고리즘이 효율적인지는 잘 모르겠다..

(아니라면 이유 좀 알려주세요.. 😂)

이거보다 bisect 함수를 공부해보는게 더 좋을 것 같다.

그리고 count 안에서 존재하는지 여부를 확인할 때, 리스트는 시간초과가 발생하고 set과 dict는 발생하지 않는다.

list보다 set, dict에서 시간복잡도가 확실히 낮다는 것을 알 수 있었다.