티어 : Silver 4 시간 제한 : 2 초 메모리 제한 : 256 MB 알고리즘 분류 : 자료구조, 큐
문제
요세푸스 문제는 다음과 같다.
1번부터 N번까지 N명의 사람이 원을 이루면서 앉아있고, 양의 정수 K(≤ N)가 주어진다. 이제 순서대로 K번째 사람을 제거한다. 한 사람이 제거되면 남은 사람들로 이루어진 원을 따라 이 과정을 계속해 나간다. 이 과정은 N명의 사람이 모두 제거될 때까지 계속된다. 원에서 사람들이 제거되는 순서를 (N, K)-요세푸스 순열이라고 한다. 예를 들어 (7, 3)-요세푸스 순열은 <3, 6, 2, 7, 5, 1, 4>이다.
N과 K가 주어지면 (N, K)-요세푸스 순열을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)
출력
예제와 같이 요세푸스 순열을 출력한다.
예제 입출력
Algorithm
구현 1. list의 index에 해당하는 숫자 answer에 저장하고 remove 2. index의 값 K씩 증가시키며 list 비어있지 않을 때만 반복되도록 구현
Code
N, K = map(int, input().split())
nums = list(range(1, N+1))
index = K-1
answer = []
while True:
# 현재 index의 사람 없애기
answer.append(nums[index])
nums = nums[:index] + nums[index+1:]
if not nums:
break
index = (index + K-1) % len(nums)
print('<' + ', '.join(list(map(str, answer))) + '>')
티어 : Silver 4 시간 제한 : 0.5 초 (추가 시간 없음) 메모리 제한 : 256 MB 알고리즘 분류 : 자료 구조, 큐
문제
정수를 저장하는 큐를 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.
명령은 총 여섯 가지이다.
push X: 정수 X를 큐에 넣는 연산이다.
pop: 큐에서 가장 앞에 있는 정수를 빼고, 그 수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 큐에 들어있는 정수의 개수를 출력한다.
empty: 큐가 비어있으면 1, 아니면 0을 출력한다.
front: 큐의 가장 앞에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
back: 큐의 가장 뒤에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
입력
첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.
출력
출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.
예제 입출력
Algorithm
구현 - Simulation, Queue
Code
import sys
from collections import deque
input = sys.stdin.readline
N = int(input())
queue = deque()
for _ in range(N):
orders = input().rstrip()
# orders에 공백이 포함되어있으면 나누기
if ' ' in orders:
order, num = orders.split()
num = int(num)
else:
order = orders
if order == 'push':
queue.append(num)
elif order == 'pop':
# 정수가 없는 경우
if not queue:
print(-1)
else:
print(queue[0])
queue.popleft()
elif order == 'size':
print(len(queue))
elif order == 'empty':
# 비어있으면 1
if not queue:
print(1)
else:
print(0)
elif order == 'front':
# 큐에 정수가 없으면 -1 출력
if not queue:
print(-1)
else:
print(queue[0])
else:
# 큐에 정수가 없으면 -1 출력
if not queue:
print(-1)
else:
print(queue[-1])
티어 : Gold 5 시간 제한 : 1 초 메모리 제한 : 128 MB 알고리즘 분류 : 구현, 자료 구조, 시뮬레이션, 덱, 큐
문제
'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다.
게임은 NxN 정사각 보드위에서 진행되고, 몇몇 칸에는 사과가 놓여져 있다. 보드의 상하좌우 끝에 벽이 있다. 게임이 시작할때 뱀은 맨위 맨좌측에 위치하고 뱀의 길이는 1 이다. 뱀은 처음에 오른쪽을 향한다.
뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따른다.
먼저 뱀은 몸길이를 늘려 머리를 다음칸에 위치시킨다.
만약 이동한 칸에 사과가 있다면, 그 칸에 있던 사과가 없어지고 꼬리는 움직이지 않는다.
만약 이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워준다. 즉, 몸길이는 변하지 않는다.
사과의 위치와 뱀의 이동경로가 주어질 때 이 게임이 몇 초에 끝나는지 계산하라.
입력
첫째 줄에 보드의 크기 N이 주어진다. (2 ≤ N ≤ 100) 다음 줄에 사과의 개수 K가 주어진다. (0 ≤ K ≤ 100)
다음 K개의 줄에는 사과의 위치가 주어지는데, 첫 번째 정수는 행, 두 번째 정수는 열 위치를 의미한다. 사과의 위치는 모두 다르며, 맨 위 맨 좌측 (1행 1열) 에는 사과가 없다.
다음 줄에는 뱀의 방향 변환 횟수 L 이 주어진다. (1 ≤ L ≤ 100)
다음 L개의 줄에는 뱀의 방향 변환 정보가 주어지는데, 정수 X와 문자 C로 이루어져 있으며. 게임 시작 시간으로부터 X초가 끝난 뒤에 왼쪽(C가 'L') 또는 오른쪽(C가 'D')로 90도 방향을 회전시킨다는 뜻이다. X는 10,000 이하의 양의 정수이며, 방향 전환 정보는 X가 증가하는 순으로 주어진다.
출력
첫째 줄에 게임이 몇 초에 끝나는지 출력한다.
예제 입출력
Algorithm
구현 - 시뮬레이션 1. board를 리스트로 구현 ☞ 사과가 있는 칸은 True, 사과가 없는 칸은 False 2. 현재 뱀의 몸이 닿아있는지 여부가 담긴 snake 리스트 구현 ☞ 몸이 닿아있으면 True, 닿아있지 않으면 False 3. 반복문 1번 돌 때마다 snake의 다음 칸 True, 첫 번째 칸 False ☞ 사과 먹으면 첫 번째 칸 놔두기 4. 반복문 1번 돌 때마다 초 증가 ☞ 초 == x+1이면 c의 방향으로 이동 ☞ 현재 방향 (상, 하, 좌, 우) 저장해두고 상일 때 D이면 우, L이면 좌로 변경 하일 때 D이면 좌, L이면 우로 변경 좌일 때 D이면 상, L이면 하로 변경 우일 때 D이면 하, L이면 상으로 변경 5. 다음 칸의 snake가 True이거나 board 범위 벗어나면 break
Code
import sys
input = sys.stdin.readline
# 현재 방향과 변경할 방향으로 인자로 줬을 때 다음 방향을 return하는 함수
def return_index(index, C):
# 현재 방향이 상인 경우
if index == 0:
# C가 D이면 우로 변경
if C == 'D':
index = -1
# C가 L이면 좌로 변경
else:
index = 2
# 현재 방향이 하인 경우
elif index == 1:
# C가 D이면 좌로 변경
if C == 'D':
index = 2
# C가 L이면 우로 변경
else:
index = -1
# 현재 방향이 좌인 경우
elif index == 2:
# C가 D이면 상으로 변경
if C == 'D':
index = 0
# C가 L이면 하로 변경
else:
index = 1
# 현재 방향이 우인 경우
else:
# C가 D이면 하로 변경
if C == 'D':
index = 1
# C가 L이면 상으로 변경
else:
index = 0
return index
# board 구현
N = int(input())
board = [[False for _ in range(N+1)] for _ in range(N+1)]
# 뱀 리스트 구현
snake = [[False for _ in range(N+1)] for _ in range(N+1)]
# 사과 위치 저장
K = int(input())
for _ in range(K):
x, y = map(int, input().split())
# 사과 위치 True로 변환
board[x][y] = True
# 뱀의 방향 변환 정보 저장
L = int(input())
move = []
for _ in range(L):
time, direction = input().split()
move.append((int(time), direction))
# 방향 : 상, 하, 좌, 우
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
index = -1 # 현재 방향
x = 1 # 현재 위치
y = 1 # 현재 위치
# 현재 위치에 뱀 저장
snake[x][y] = True
snake_length = 1 # 뱀 길이
last_loc = [1, 1]
time = 1
index_record = []
while True:
# 현재 시간이 X+1이면 C의 방향으로 방향 회전
if move and time == move[0][0]+1:
index = return_index(index, move[0][1])
move = move[1:]
# 현재 방향으로 이동
nx = x+dx[index]
ny = y+dy[index]
# 다음 칸의 위치에 뱀의 몸이 있거나 board의 범위를 벗어나면 break
if nx < 1 or nx > N or ny < 1 or ny > N or snake[nx][ny]:
break
index_record.append(index)
# 다음 칸으로 뱀 이동
snake[nx][ny] = True
snake_length += 1
# 사과가 있으면 사과 삭제
if board[nx][ny]:
board[nx][ny] = False
else: # 사과가 없으면 첫 칸에서 뱀 삭제
snake[last_loc[0]][last_loc[1]] = False
snake_length -= 1
last_loc[0] += dx[index_record[-snake_length]]
last_loc[1] += dy[index_record[-snake_length]]
# 시간 증가
time += 1
# x, y 갱신
x = nx
y = ny
print(time)
티어 : Silver 4 시간 제한 : 2 초 메모리 제한 : 512 MB 알고리즘 분류 : 구현, 자료 구조, 큐
문제
요세푸스 문제는 다음과 같다.
1번부터 N번까지 N명의 사람이 원을 이루면서 앉아있고, 양의 정수 K(≤ N)가 주어진다. 이제 순서대로 K번째 사람을 제거한다. 한 사람이 제거되면 남은 사람들로 이루어진 원을 따라 이 과정을 계속해 나간다. 이 과정은 N명의 사람이 모두 제거될 때까지 계속된다. 원에서 사람들이 제거되는 순서를 (N, K)-요세푸스 순열이라고 한다. 예를 들어 (7, 3)-요세푸스 순열은 <3, 6, 2, 7, 5, 1, 4>이다.
N과 K가 주어지면 (N, K)-요세푸스 순열을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 1,000)
출력
예제와 같이 요세푸스 순열을 출력한다.
예제 입출력
Algorithm
Queue 구현 - deque library 사용 1. queue에 1부터 N까지 숫자로 채움 2. append(queue[0]), popleft()를 두 번 수행 3. print(queue[0]), popleft() 수행 4. queue가 빌 때까지 반복
Code
from collections import deque
N, K = map(int, input().split())
queue = deque([i for i in range(1, N+1)])
answer = []
while queue:
# append, popleft 두 번 수행
for _ in range(K - 1):
queue.append(queue[0])
queue.popleft()
# print, popleft 수행
answer.append(queue[0])
queue.popleft()
print('<', end = '')
for i in range(len(answer)):
if i == len(answer) - 1:
print(answer[i], end = '>')
else:
print(answer[i], end = ', ')
티어 : Silver 2 시간 제한 : 2 초 (추가 시간 없음) 메모리 제한 : 128 MB 알고리즘 분류 : 자료 구조, 큐
문제
N장의 카드가 있다. 각각의 카드는 차례로 1부터 N까지의 번호가 붙어 있으며, 1번 카드가 제일 위에, N번 카드가 제일 아래인 상태로 순서대로 카드가 놓여 있다.
이제 다음과 같은 동작을 카드가 한 장 남을 때까지 반복하게 된다. 우선, 제일 위에 있는 카드를 바닥에 버린다. 그 다음, 제일 위에 있는 카드를 제일 아래에 있는 카드 밑으로 옮긴다.
예를 들어 N=4인 경우를 생각해 보자. 카드는 제일 위에서부터 1234 의 순서로 놓여있다. 1을 버리면 234가 남는다. 여기서 2를 제일 아래로 옮기면 342가 된다. 3을 버리면 42가 되고, 4를 밑으로 옮기면 24가 된다. 마지막으로 2를 버리고 나면, 남는 카드는 4가 된다.
N이 주어졌을 때, 제일 마지막에 남게 되는 카드를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 정수 N(1 ≤ N ≤ 500,000)이 주어진다.
출력
첫째 줄에 남게 되는 카드의 번호를 출력한다.
예제 입출력
Algorithm
Queue 구현 - deque library 사용 1. queue에 1부터 n까지 숫자로 채움 2. popleft()로 맨 위의 카드 버림 3. append(queue[0])로 맨 위의 카드 맨 마지막으로 보내기 4. popleft()로 맨 위의 카드 버림 5. 카드가 한 장 남을 때까지 반복
Code
from collections import deque
N = int(input())
queue = deque([i for i in range(1, N+1)])
while len(queue) > 1:
# 맨 위의 카드 버리기
queue.popleft()
# 그 다음 맨 위의 카드 버리고 캔 아래 카드 아래로 보내기
queue.append(queue[0])
queue.popleft()
print(queue[0])
티어 : Silver 4 시간 제한 : 1 초 (Python 3: 3초) 메모리 제한 : 512 MB 알고리즘 분류 : 자료 구조, 큐
문제
정수를 저장하는 큐를 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.
명령은 총 여섯 가지이다.
push X: 정수 X를 큐에 넣는 연산이다.
pop: 큐에서 가장 앞에 있는 정수를 빼고, 그 수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 큐에 들어있는 정수의 개수를 출력한다.
empty: 큐가 비어있으면 1, 아니면 0을 출력한다.
front: 큐의 가장 앞에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
back: 큐의 가장 뒤에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
입력
첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 2,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.
출력
출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.
예제 입출력
Algorithm
Queue 구현 - deque library 사용 1. 입력받을 때 readline().rstrip()으로 입력 2. push이면 append 3. pop이면 빈 리스트면 -1출력, 비어있지 않으면 del queue[0] 4. size이면 len(queue) 5. empty이면 빈 리스트면 1, 비어있지 않으면 0 출력 6. front이면 빈 리스트면 -1, 비어있지 않으면 print(queue[0]) 7. back이면 빈 리스트면 -1, 비어있지 않으면 print(queue[-1])
Code
import sys
from collections import deque
input = sys.stdin.readline
N = int(input())
queue = deque([])
for _ in range(N):
order = input().rstrip()
# order가 push이면
if order[:4] == 'push':
queue.append(int(order[5:]))
# order가 pop이면
elif order == 'pop':
if not queue:
print(-1)
else:
print(queue[0])
# del queue[0]
queue.popleft()
# order가 size이면
elif order == 'size':
print(len(queue))
# order가 empty이면
elif order == 'empty':
if queue:
print(0)
else:
print(1)
# order가 front이면
elif order == 'front':
if not queue:
print(-1)
else:
print(queue[0])
# order가 back이면
else:
if not queue:
print(-1)
else:
print(queue[-1])