728x90
부품 찾기
A. 문제
우리 매장에는 부품이 N개 있다. 각 부품은 정수 형태의 고유한 번호가 있다.
손님이 M개 종류의 부품을 대량으로 구매하겠다며 견적서를 요청한다.
손님이 문의한 부품 M개 종류를 모두 확인해서 견적서를 작성해야 한다.
이때, 가게 안에 부품이 모두 있는지 확인하는 프로그램을 작성하자.
이때, 손님이 요청한 부품 번호의 순서대로 부품을 확인해 부품이 있으면 yes, 없으면 no를 공백으로 구분하여 출력한다.
b. 입력 조건
첫째 줄에 정수 N이 주어진다.1 <= N <= 1,000,000둘째 줄에는 공백으로 구분하여 N개의 정수가 주어진다.정수는 1보다 크고 1,000,000 이하이다.셋째 줄에는 정수 M이 주어진다1 <= M <= 100,000넷째 줄에는 공백으로 구분하여 M개의 정수가 주어진다.정수는 1보다 크고 1,000,000 이하이다.
테스트케이스
5
8 3 7 9 2
3
5 7 9
no yes yes
c. 출력 조건
첫째 줄에 공백으로 구분하여 각 부품이 존재하면 yes, 없으면 no를 출력한다.
더보기
# 이진 탐색 소스코드 구현 (반복문)
def binary_search(array, target, start, end):
while start <= end:
mid = (start + end) // 2
# 찾은 경우 중간점 인덱스 반환
if array[mid] == target:
return mid
# 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인
elif array[mid] > target:
end = mid - 1
# 중간점의 값보다 찾고자 하는 값이 작은 경우 오른쪽 확인
else:
start = mid + 1
return None
# N(가게의 부품 개수) 입력
n = int(input())
# 가게에 있는 전체 부품 번호를 공백을 기준으로 구분하여 입력
array = list(map(int, input().split()))
array.sort() # 이진 탐색을 수행하기 위해 사전에 정렬 수행
# M(손님이 확인 요청한 부품 개수) 입력
m = int(input())
# 손님이 확인 요청한 전체 부품 번호를 공백을 기준으로 구분하여 입력
x = list(map(int, input().split()))
# 손님이 확인 요청한 부품 번호를 하나씩 확인
for i in x:
# 해당 부품이 존재하는지 확인
result = binary_search(array, i, 0, n - 1)
if result != None:
print('yes', end=' ')
else:
print('no', end=' ')
# N(가게의 부품 개수) 입력, 계수 정렬로 해결
n = int(input())
array = [0] * 1000001
# 가게에 있는 전체 부품 번호를 입력 받아서 기록
for i in input().split():
array[int(i)] = 1
# M(손님이 확인 요청한 부품 개수) 입력
m = int(input())
# 손님이 확인 요청한 전체 부품 번호를 공백을 기준으로 구분하여 입력
x = list(map(int, input().split()))
# 손님이 확인 요청한 부품 번호를 하나씩 확인
for i in x:
# 해당 부품이 존재하는지 확인
if array[i] == 1:
print('yes', end=' ')
else:
print('no', end=' ')
# N(가게의 부품 개수) 입력, 집합(set)자료형으로 해결
n = int(input())
# 가게에 있는 전체 부품 번호를 입력 받아서 집합(Set) 자료형에 기록
array = set(map(int, input().split()))
# M(손님이 확인 요청한 부품 개수) 입력
m = int(input())
# 손님이 확인 요청한 전체 부품 번호를 공백을 기준으로 구분하여 입력
x = list(map(int, input().split()))
# 손님이 확인 요청한 부품 번호를 하나씩 확인
for i in x:
# 해당 부품이 존재하는지 확인
if i in array:
print('yes', end=' ')
else:
print('no', end=' ')
떡볶이 떡 만들기
A. 문제
떡볶이 떡을 만든다. 떡의 길이가 일정하지 않다. 한 봉지에 들어가는 떡의 총 길이는 절단기로 잘라서 맞춰준다.
절단기에 높이(H)를 지정하면 줄지어진 떡을 한 번에 절단한다. 높이가 H보다 긴 떡은 H 위가 잘리고, 낮은 떡은 잘리지 않는다.
손님이 요청한 총 길이가 M이면 적어도 M만큼의 떡을 얻기 위해 절단기에 설정할 수 있는 높이의 최댓값을 구하라.
a. 예를 들면.
높이가 19, 14, 10, 17cm인 떡이 나란히 있다. 절단기 높이를 15cm로 지정하고 자른 뒤 떡의 높이는 15, 14, 19, 15cm가 될 것이고, 잘린 떡의 길이는 4, 0, 0, 2cm이다. 손님은 6cm만큼의 길이를 가져간다.
b. 입력 조건
첫째 줄에 떡의 개수 N과 요청한 떡의 길이 M이 주어진다1 <= N <= 1,000,0001 <= M <= 2,000,000,000둘째 줄에는 떡의 개별 높이가 주어진다.떡 높이의 총합은 항상 M 이상이므로, 손님은 필요한 양만큼 떡을 사갈 수 있다높이는 10억보다 작거나 같은 양의 정수 또는 0이다.
c. 출력 조건
적어도 M만큼의 떡을 집에 가져가기 위해 절단기에 설정할 수 있는 높이의 최댓값을 출력하라.
더보기
# 떡의 개수(N)와 요청한 떡의 길이(M)을 입력
n, m = list(map(int, input().split(' ')))
# 각 떡의 개별 높이 정보를 입력
array = list(map(int, input().split()))
# 이진 탐색을 위한 시작점과 끝점 설정
start = 0
end = max(array)
# 이진 탐색 수행 (반복적)
result = 0
while(start <= end):
total = 0
mid = (start + end) // 2
for x in array:
# 잘랐을 때의 떡볶이 양 계산
if x > mid:
total += x - mid
# 떡볶이 양이 부족한 경우 더 많이 자르기 (오른쪽 부분 탐색)
if total < m:
end = mid - 1
# 떡볶이 양이 충분한 경우 덜 자르기 (왼쪽 부분 탐색)
else:
result = mid # 최대한 덜 잘랐을 때가 정답이므로, 여기에서 result에 기록
start = mid + 1
# 정답 출력
print(result)
정렬된 배열에서 특정 수의 개수 구하기
A. 문제
N개의 원소를 포함하고 있는 수열이 오름차순으로 정렬되어 있다. 이때 이 수열에서 x가 등장하는 횟수를 계산하라.
단, 이 문제는 시간 복잡도 O(logN)으로 알고리즘을 설계하지 않으면 시간 초과 판정을 받는다.
a. 예를 들면.
수열 {1, 1, 2 ,2 ,2 ,2, 3}이 있을 때 x=2라면, 현재 수열에서 값이 2인 원소가 4개이므로 4를 출력한다.
b. 입력 조건
첫째 줄에 N과 x가 정수 형태로 공백으로 구분되어 입력된다.1 <= N <= 1,000,000-1e9 <= x <= 1e9둘째 줄에 N개의 원소가 정수 형태로 공백으로 구분되어 입력된다-1e9 <= 각 원소의 값 <= 1e9
c. 출력 조건
수열의 원소 중에서 값이 x인 원소의 개수를 출력한다. 단 값이 x인 원소가 하나도 없다면 -1일 출력한다.
더보기
from bisect import bisect_left, bisect_right
# 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수
def count_by_range(array, left_value, right_value):
right_index = bisect_right(array, right_value)
left_index = bisect_left(array, left_value)
return right_index - left_index
n, x = map(int, input().split()) # 데이터의 개수 N, 찾고자 하는 값 x 입력 받기
array = list(map(int, input().split())) # 전체 데이터 입력 받기
# 값이 [x, x] 범위에 있는 데이터의 개수 계산
count = count_by_range(array, x, x)
# 값이 x인 원소가 존재하지 않는다면
if count == 0:
print(-1)
# 값이 x인 원소가 존재한다면
else:
print(count)
고정점 찾기
A. 문제
고정점이란, 수열의 원소 중에서 그 값이 인덱스와 동일한 원소를 의미한다.
하나의 수열이 N개의 서로 다른 원소를 포함하고 있으며, 모든 원소가 오름차순으로 정렬되어 있다. 이때 이 수열에서 고정점이 있다면, 고정점을 출력하고, 고정점이 없다면, - 1을 출력한다.
단, 이 문제는 시간 복잡도 O(logN)으로 알고리즘을 설계하지 않으면 '시간 초과' 판정을 받는다.
a. 예를 들면.
고정점을 예를 들면 수열 a = {-15, -4, 2, 8, 13}이 있을 때 a[2] = 2이므로, 고정점은 2가 된다.
b. 입력 조건
첫째 줄에 N이 입력된다.1 <= N <= 1,000,000둘째 줄에 N개의 원소가 정수 형태로 공백으로 구분되어 입력된다.-10e9 <= 각 원소의 값 <= 10e9
c. 출력 조건
고정점을 출력한다, 고정점이 없다면 -1을 출력한다.
더보기
# 이진 탐색 소스코드 구현(재귀 함수)
def binary_search(array, start, end):
if start > end:
return None
mid = (start + end) // 2
# 고정점을 찾은 경우 인덱스 반환
if array[mid] == mid:
return mid
# 중간점이 가리키는 값보다 중간점이 작은 경우 왼쪽 확인
elif array[mid] > mid:
return binary_search(array, start, mid - 1)
# 중간점이 가리키는 값보다 중간점이 큰 경우 오른쪽 확인
else:
return binary_search(array, mid + 1, end)
n = int(input())
array = list(map(int, input().split()))
# 이진 탐색(Binary Search) 수행
index = binary_search(array, 0, n - 1)
# 고정점이 없는 경우 -1 출력
if index == None:
print(-1)
# 고정점이 있는 경우 해당 인덱스 출력
else:
print(index)
공유기 설치
더보기
# 집의 개수(N)와 공유기의 개수(C)를 입력 받기
n, c = list(map(int, input().split(' ')))
# 전체 집의 좌표 정보를 입력 받기
array = []
for _ in range(n):
array.append(int(input()))
array.sort() # 이진 탐색 수행을 위해 정렬 수행
start = 1 # 가능한 최소 거리(min gap)
end = array[-1] - array[0] # 가능한 최대 거리(max gap)
result = 0
while(start <= end):
mid = (start + end) // 2 # mid는 가장 인접한 두 공유기 사이의 거리(gap)을 의미
# 첫째 집에는 무조건 공유기를 설치한다고 가정
value = array[0]
count = 1
# 현재의 mid 값을 이용해 공유기를 설치하기
for i in range(1, n): # 앞에서부터 차근차근 설치
if array[i] >= value + mid:
value = array[i]
count += 1
if count >= c: # C개 이상의 공유기를 설치할 수 있는 경우, 거리를 증가시키기
start = mid + 1
result = mid # 최적의 결과를 저장
else: # C개 이상의 공유기를 설치할 수 없는 경우, 거리를 감소시키기
end = mid - 1
print(result)
가사 탐색
더보기
# 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수
def count_by_range(a, left_value, right_value):
right_index = bisect_right(a, right_value)
left_index = bisect_left(a, left_value)
return right_index - left_index
# 모든 단어들을 길이마다 나누어서 저장하기 위한 리스트
array = [[] for _ in range(10001)]
# 모든 단어들을 길이마다 나누어서 뒤집어 저장하기 위한 리스트
reversed_array = [[] for _ in range(10001)]
def solution(words, queries):
answer = []
for word in words: # 모든 단어를 접미사 와일드카드 배열, 접두사 와일드카드 배열에 각각 삽입
array[len(word)].append(word) # 단어를 삽입
reversed_array[len(word)].append(word[::-1]) # 단어를 뒤집어서 삽입
for i in range(10001): # 이진 탐색을 수행하기 위해 각 단어 리스트 정렬 수행
array[i].sort()
reversed_array[i].sort()
for q in queries: # 쿼리를 하나씩 확인하며 처리
if q[0] != '?': # 접미사에 와일드 카드가 붙은 경우
res = count_by_range(array[len(q)], q.replace('?', 'a'), q.replace('?', 'z'))
else: # 접두사에 와일드 카드가 붙은 경우
res = count_by_range(reversed_array[len(q)], q[::-1].replace('?', 'a'), q[::-1].replace('?', 'z'))
# 검색된 단어의 개수를 저장
answer.append(res)
return answer
'프로그래밍 > 알고리즘' 카테고리의 다른 글
이코테 최단경로 파이썬 (0) | 2023.02.12 |
---|---|
이코테 DP 파이썬 (0) | 2023.02.12 |
이코테 정렬 파이썬 (0) | 2023.02.12 |
이코테 DFS/BFS 파이썬 (0) | 2023.02.12 |
이코테 구현 파이썬 (0) | 2023.02.12 |
댓글