난이도 : D3
문제번호 : 5207
※ 저의 풀이가 무조건적인 정답은 아닙니다.
다른 코드가 좀더 효율적이고 좋을 수 있습니다.
다른사람들의 풀이는 언제나 참고만 하시기 바랍니다.
문제 주소 및 출처입니다.
목차
1. 문제 설명
2. 문제 해석
3. 소스 코드
1. 문제 설명
서로 다른 정수 N개가 주어지면 정렬한 상태로 리스트 A에 저장한다. 그런 다음 리스트 B에 저장된 M개의 정수에 대해 A에 들어있는 수인지 이진 탐색을 통해 확인하려고 한다. |
예를 들어 10을 찾는 경우 오른쪽-오른쪽 구간을 선택하므로 조건에 맞지 않는다 5를 찾는 경우 m에 위치하므로 조건에 맞는다. 이때 m에 찾는 원소가 있는 경우 방향을 따지지 않는다. M개의 정수 중 조건을 만족하는 정수의 개수를 알아내는 프로그램을 만드시오. |
입력
첫 줄에 테스트케이스의 수 T가 주어진다. 1<=T<=50 |
출력
각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 답을 출력한다. |
예시
입력 | 출력 |
3 3 3 1 2 3 2 3 4 3 5 1 3 5 2 4 6 8 10 5 5 1 3 5 7 9 1 2 3 4 5 |
#1 2 #2 0 #3 3 |
2. 문제풀이
이분탐색을 할줄안다면 쉽게 풀 수 있는 문제이다. |
3. 소스코드
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
|
#D3 5207 이진탐색
for t in range(int(input())):
answer = 0
N, M = map(int, input().split())
# 이분탐색은 정렬을 기본조건으로 한다.
A = sorted(list(map(int, input().split())))
B = list(map(int, input().split()))
for b in B:
# 중간을 탐색하기 때문에 최소점과 최대점을 잡아준다.
min_idx = 0
max_idx = N - 1
# 왼쪽으로 갔는지 오른쪽으로 갔는지 체크하기 위한 용도
flag = 0
# 탐색범위가 같아지거나 엇갈릴때까지 반복한다.
while min_idx <= max_idx:
# 중간지점의 위치를 구한다.
avg_idx = (min_idx+max_idx)//2
# 중간지점의 값이 정답이라면 answer를 늘리고 반복문을 중지한다.
if A[avg_idx] == b:
answer += 1
break
# 선택한 인덱스 값이 찾는값보다 크다면
elif A[avg_idx] > b:
# 선택한 인덱스 위쪽은 필요없으므로 최대 인덱스 위치를 수정한다.
max_idx = avg_idx - 1
# 이전에도 왼쪽을 선택했다면 중지
if flag == 1: break
# 왼쪽으로 갔다고 표시한다.
flag = 1
else:
# 반대의 상황이라면 최소값을 바꿔준다.
min_idx = avg_idx + 1
# 이전에 오른쪽으로 갔다면 중지
if flag == -1: break
# 오른쪽으로 갔다고 표시한다.
flag = -1
print('#{} {}'.format(t+1, answer))
|
'코딩테스트 > SWExpertAcademy' 카테고리의 다른 글
이진수 Python(SW Expert Academy) (0) | 2020.05.14 |
---|---|
이진탐색 Python(SW Expert Academy) (0) | 2020.05.13 |
수열 편집 Python(SW Expert Academy) (0) | 2020.04.17 |
숫자 추가 Python(SW Expert Academy) (0) | 2020.04.16 |
노드의 합 Python(SW Expert Academy) (0) | 2020.04.15 |
댓글