문제
숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 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
숫자 카드와 비슷한 유형이지만 그 갯수를 나타낸다.
문제 요약
가지고 있는 카드 리스트와 확인할 리스트에서 같은 숫자가 몇개나 있나 확인하는 문제
접근 방법
1. 재귀 : 시간 초과
이전 처럼 set을 사용하여 중복된 것을 제거할 수는 없으므로 제외
따라서 이전처럼 sort를 사용하여 정렬을하고 이분 검색하여 갯수를 파악
이때 저번처럼 바로 return 함수를 한 것이아니라 값을 저장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import sys
input =sys.stdin.readline
print = sys.stdout.write
N = int(input())
have = list(map(int, input().split()))
have.sort()
M = int(input())
check_list = list(map(int,input().split()))
def check(c,start, end):
if start >= end:
return 0
n = (start+end)//2
re = 0
if have[n] == c:
re += 1
re+=check(c,start,n)
re+=check(c,n+1,end)
elif have[n] > c:
re += check(c,start,n)
elif have[n]<c:
re += check(c,n+1,end)
return re
for c in check_list:
print(str(check(c,0,N))+' ')
|
원인 : 아마 if have[n] == c에서 끝내지않고 주위를 추가로 확인하게 했기 때문에
2. 또 다른 방법으로 시도 : 시간 초과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
N = int(input())
n_list = list(map(int, input().split()))
n_list.sort()
M = int(input())
m_list = list(map(int, input().split()))
def add(mid,m):
left = mid
right = mid +1
ret = 0
l_done = False
r_done = False
while not l_done or not r_done:
if left > -1 and n_list[left] == m:
ret += 1
left -= 1
else:
l_done = True
if right < N and n_list[right] == m:
ret += 1
right += 1
else:
r_done = True
return ret
def find(start, end, m):
if start > end:
return 0
elif start == end:
if n_list[start] == m:
return add(start,m)
else:
return 0
mid = (start + end) // 2
if n_list[mid] == m:
return add(mid,m)
elif n_list[mid] < m:
return find(mid+1, end, m)
else:
return find(start, mid, m)
for m in m_list:
print(find(0,N-1,m))
|
이번에는 정렬을 했기때문에 주위에 같은 수가 있다는 것을 토대로 주위를 차례로 보게함
이렇게 시도하면서 전부 같은 수면 엄청 오래걸려서 안되겠다는 생각과 함께 일단 끝까지 짜보았으나 역시 실패
3. dictonary이용 : 성공
먼저 같은 수가 몇개 있는지를 세고 찾으면 해당 수의 갯수를 출력하자는 발상
따라서 입력 값들을 하나하나 검사하여 dict에 없으면 추가하고 있으면 갯수를 한개 업
이후 출력할때 안에 있는지만 확인하면 됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import sys
input = sys.stdin.readline
N = int(input())
have = list(map(int, input().split()))
have.sort()
M = int(input())
check_list = list(map(int,input().split()))
dic = {}
for n in have :
if n in dic:
dic[n] += 1
else:
dic[n] = 1
print(' '.join(str(dic[n]) if n in dic else '0' for n in check_list))
|
물론 이분 분할로 찾는 것도 가능
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import sys
input = sys.stdin.readline
N = int(input())
have = list(map(int, input().split()))
have.sort()
M = int(input())
check_list = list(map(int,input().split()))
dic = {}
for n in have:
if n in dic:
dic[n] += 1
else:
dic[n] = 1
def check(c,start, end):
# 역적 = 없다는 것
if start >= end:
return False
n = (start+end)//2
if have[n] == c:
return True
if have[n] > c:
return check(c,start,n)
else:
return check(c,n+1,end)
for c in check_list:
if check(c,0,N):
print(dic[c], end=' ')
else:
print("0 ",end="")
|
여기서도 dic에 새로운 값을 넣을때
새로운 변수에 데이터를 새로 넣어서 set을 한것과 동일한 리스트로 만들어서 찾는 것도 가능
'알고리즘 문제 > 백준' 카테고리의 다른 글
알고리즘 - 집합과 맵(1269 대칭 차집합) (0) | 2022.08.06 |
---|---|
알고리즘 - 집합과 맵 (1764 듣보잡) (0) | 2022.08.06 |
알고리즘 - 집합과 맵 ( 1620 나는야 포켓몬 마스터 이다솜 ) (0) | 2022.08.06 |
알고리즘 - 집합과 맵(14425 문자열 집합) (0) | 2022.08.06 |
알고리즘 - 집합 (10815 숫자 카드) (0) | 2022.08.06 |