[백준/오늘의 문제] 04.28

ZenTechie·2023년 4월 28일
0

PS

목록 보기
49/53

문제

난이도번호문제 이름
1021회전하는 큐
15886내 선물을 받아줘 2
16508전공책
1005ACM Craft

HOW TO SOLVE

  • 회전하는 큐 : 단순 구현
  • 내 선물을 받아줘 2 : 단순 구현
  • 전공책 : DFS + 백트래킹 (답 참고 + 다시 풀자.. )
  • ACM Craft : 아직 안 품

회전하는 큐

'''
- 양방향으로 입/출력이 가능한 큐를 구현하는 것이 핵심
- 덱을 사용하면 양방향 입/출력이 가능하다.
- 왼쪽 이동 / 오른쪽 이동이 가능
- 주어진 원소의 위치를 뽑아내는데 드는 연산의 최솟값 구하기
    - 덱에서 현재 원소의 위치를 구한다.
    - 현재 원소의 왼쪽과 오른쪽에 있는 원소들의 개수 중 작은 것을 선택해서 2 or 3번 연산 수행
'''
from collections import deque

n, m = map(int, input().split()) # 큐의 크기, 뽑아내려고 하는 수의 개수
indexes = list(map(int, input().split())) # 뽑아내려고 하는 수의 위치

q = deque([i for i in range(1, n + 1)]) # 덱 초기화

cnt = 0 # 총 연산의 횟수

# 뽑아내려는 원소의 위치를 순회하면서
for index in indexes:
    if q[0] == index: # 첫 번쨰 원소와 일치하면
        q.popleft() # 그냥 뽑아낸다.
    else: # 일치하지 않으면
        left = q.index(index) # 현재 원소의 왼쪽에 있는 수들의 개수
        right = len(q) - left # 오른쪽에 있는 수들의 개수
        if left <= right: # 왼쪽에 개수가 더 적다면
            for _ in range(left): 
                q.append(q.popleft()) # 왼쪽 원소를 뽑아서 덱의 오른쪽에 붙인다.
                cnt += 1 # 연산 횟수 증가
            q.popleft() # 해당 원소 뽑아내기
        else: # 오른쪽에 개수가 더 적다면
            for _ in range(right): 
                q.appendleft(q.pop()) # 오른쪽 원소를 뽑아서 덱의 왼쪽에 붙인다.
                cnt += 1 # 연산 횟수 증가
            q.popleft() # 해당 원소 뽑아내기

# 출력
print(cnt)

내 선물을 받아줘 2

'''
- 구사과의 초기 위치와 관계없이 선물을 주는 방법
- 최소 몇 개의 칸 위에 선물을 놓으면, 구사과가 항상 선물을 가져가는가?
- E : x + 1 / W : x - 1
'''
n = int(input())
graph = list(input())

cnt = 0 # 선물을 놓을 칸의 개수

# EW 라면 오른쪽으로 갔다가 왼쪽으로 가는 것을 무한히 반복함.
# 그러므로 EW의 개수만 세면 된다.
for i in range(len(graph) - 1):
    if graph[i] == 'E' and graph[i + 1] == 'W': # 이어진 문자열이 EW 라면
        cnt += 1

# 출력
print(cnt)

전공책

from collections import Counter

'''
- 단어 T를 만들기 위해서 선택해야 하는 전공책의 가장 적은 가격의 합 구하기
'''

# 전공책 조합 구하기
def helper(index, _sum):
    global _min
    if index == n:
        if can_make_t():
            _min = min(_min, _sum)
        return
    
    # 현재 전공책 선택하기
    for x in _list[index][1]:
        alpha_count[ord(x) - ord('A')] += 1
    
    helper(index + 1, _sum + int(_list[index][0]))
    
    # 현재 전공책 선택하지 않기
    for x in _list[index][1]:
        alpha_count[ord(x) - ord('A')] -= 1
    
    helper(index + 1, _sum)
    
# 만든 전공책 조합으로 t를 만들 수 있는지
def can_make_t():
    for i in range(26):
        if alpha_count[i] < t_count[i]:
            return False
    return True

t = input() # 만드려는 단어
n = int(input()) # 전공책의 개수

_list = []
alpha_count = [0] * 26 # 전공책에 포함된 알파벳 개수
t_count = [0] * 26 # t에 포함된 알파벳 개수
_min = int(1e9) # 최소 가격

# t에 포함된 알파벳 리스트 초기화
for i in t:
    t_count[ord(i) - ord('A')] += 1

for _ in range(n):
    c, w = input().split()
    # _list.append((c, Counter(w)))
    _list.append((c, w))

helper(0, 0)

print(_min if _min != int(1e9) else -1)

ACM Craft

profile
데브코스 진행 중.. ~ 2024.03

0개의 댓글