✅ 08 회차 모의고사 D-23일
🚀 1차 코딩테스트 대비
- 백준 20006 (랭킹전 대기열)
- 백준 17087 (숨바꼭질 6)
- 백준 13414 (수강신청)
- 백준 16953 (A → B)
- SQL 자동차 평균 대여 기간 구하기
1차 풀이
⭐ 1. 백준 20006 (랭킹전 대기열)
# 1. 알고(구현): 백준 20006 (랭킹전 대기열) - https://www.acmicpc.net/problem/20006
import sys
from io import StringIO
sys.stdin = StringIO('''10 5
10 a
15 b
20 c
25 d
30 e
17 f
18 g
26 h
24 i
28 j''')
input = sys.stdin.readline
def solve():
p, m = map(int, input().split())
rooms = []
for _ in range(p):
level, nick = input().split()
level = int(level)
for room in rooms:
if len(room) < m:
base_level = room[0][0]
if base_level-10 <= level <= base_level+10:
room.append((level, nick))
break
else:
rooms.append([(level, nick)])
for room in rooms:
print('Started!' if len(room) == m else 'Waiting!')
room.sort(key=lambda x: (x[1]))
print("\n".join(map(lambda x: f"{x[0]} {x[1]}", room)))
solve()⭐ 2. 백준 17087 (숨바꼭질 6)
# 2. 알고(수학): 백준 17087 (숨바꼭질 6) - https://www.acmicpc.net/problem/17087
import sys
from math import gcd
from io import StringIO
sys.stdin = StringIO('''3 81
33 105 57''')
input = sys.stdin.readline
def solve():
N, S = map(int, input().split())
nums = map(lambda x: abs(int(x) - S), input().split())
print(gcd(*nums))
solve()⭐ 3. 백준 13414 (수강신청)
# 3. 알고(Map): 백준 13414 (수강신청) - https://www.acmicpc.net/problem/13414
import sys
from itertools import islice
from io import StringIO
sys.stdin = StringIO('''3 8
20103324
20133221
20133221
20093778
20140101
01234567
20093778
20103325''')
input = sys.stdin.readline
def solve():
K, L = map(int, input().split())
student_ids = dict()
for order in range(L):
student_ids[input().rstrip()] = order
students = sorted(student_ids.items(), key=lambda x: x[1])
print("\n".join(stu_id for stu_id, _ in islice(students, K)))
solve()⭐ 4. 백준 16953 (A → B)
# 4. 알고(그리디): 백준 16953 (A -> B) - https://www.acmicpc.net/problem/16953
import sys
from collections import deque
from io import StringIO
sys.stdin = StringIO('''100 40021''')
input = sys.stdin.readline
def solve():
A, B = map(int, input().split())
dq = deque([(A, 1)]) # 숫자, 깊이
answer = -1
while dq:
cur, depth = dq.popleft()
depth += 1
nxt_mul = cur * 2
nxt_add = int(str(cur) + '1')
if nxt_mul == B or nxt_add == B:
answer = depth
break
if nxt_mul < B:
dq.append((nxt_mul, depth))
if nxt_add < B:
dq.append((nxt_add, depth))
print(answer)
solve()✏️ 5. SQL 자동차 평균 대여 기간 구하기
-- 5. SQL(Lv.2): 자동차 평균 대여 기간 구하기
-- https://school.programmers.co.kr/learn/courses/30/lessons/157342
SELECT
CAR_ID,
ROUND(AVG(DATEDIFF(END_DATE, START_DATE) + 1 ) , 1) AS AVERAGE_DURATION
FROM
CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY
CAR_ID
HAVING
AVERAGE_DURATION >= 7
ORDER BY
AVERAGE_DURATION DESC,
CAR_ID DESC;🚀 2차 코딩테스트 대비
- 백준 17140 (이차원 배열과 연산)
- 백준 11054 (가장 긴 바이토닉 부분 수열)
- 백준 1967 (트리의 지름)
- 백준 16197 (두 동전)
- SQL 식품분류별 가장 비싼 식품의 정보 조회하기
2차 풀이
⭐ 1. 백준 17140 (이차원 배열과 연산)
# 1. 알고(시뮬): 백준 17140 (이차원 배열과 연산) - https://www.acmicpc.net/problem/17140
import sys
from collections import Counter
from itertools import islice
from io import StringIO
sys.stdin = StringIO('''1 2 4
1 2 1
2 1 3
3 3 3''')
input = sys.stdin.readline
def solve():
r, c, k = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(3)]
def R(board):
max_row_len = 0
results = []
for row in board:
count = Counter(row)
count.pop(0, None) # 0 제거
sorted_lst = sorted(count.items(), key=lambda x: (x[1], x[0])) # 갯수 -> 숫자 순 정렬
row_result = []
for num, cnt in islice(sorted_lst, 50):
row_result.extend([num, cnt])
results.append(row_result)
max_row_len = max(max_row_len, len(row_result)) # 결과값중 가장 긴 값 저장.
new_board = [[0] * max_row_len for _ in range(len(board))]
for i, result in enumerate(results): # 배열 생성.
new_board[i][:len(result)] = result
return new_board
def C(board):
transposed = list(zip(*board))
new_list = R(transposed)
recovered = list(map(list, zip(*new_list))) # 리스트 형태로 복원.
return recovered
check_board = board
for i in range(101):
row_len = len(check_board)
col_len = len(check_board[0])
if r <= row_len and c <= col_len and check_board[r-1][c-1] == k:
print(i)
break
if row_len >= col_len:
check_board = R(check_board)
else:
check_board = C(check_board)
else:
print(-1)
solve()⭐ 2. 백준 11054 (가장 긴 바이토닉 부분 수열)
# 2. 알고(DP): 백준 11054 (가장 긴 바이토닉 부분 수열) - https://www.acmicpc.net/problem/11054
import sys
from io import StringIO
sys.stdin = StringIO('''10
1 5 2 1 4 3 4 5 2 1''')
input = sys.stdin.readline
def solve():
n = int(input())
nums = tuple(map(int, input().split()))
# 자신을 포함해서 왼쪽에 나보다 작은 수의 개수
dp_up = [1] * n
for i in range(n):
for j in range(i):
if nums[j] < nums[i]:
dp_up[i] = max(dp_up[i], dp_up[j] + 1)
dp_down = [1] * n
for i in range(n-1, -1, -1):
for j in range(n-1, i, -1):
if nums[j] < nums[i]:
dp_down[i] = max(dp_down[i], dp_down[j] + 1)
max_len = 0
for i in range(n):
max_len = max(max_len, dp_up[i] + dp_down[i] - 1) # 자기 자신 제외
print(max_len)
solve()⭐ 3. 백준 1967 (트리의 지름)
# 3. 알고(트리): 백준 1967 (트리의 지름) - https://www.acmicpc.net/problem/1967
import sys
from collections import deque
from random import randint
from io import StringIO
sys.stdin = StringIO('''12
1 2 3
1 3 2
2 4 5
3 5 11
3 6 9
4 7 1
4 8 7
5 9 15
5 10 4
6 11 6
6 12 10''')
input = sys.stdin.readline
def solve():
n = int(input())
tree = [[] for _ in range(n + 1)]
for _ in range(n-1):
a, b, c = map(int, input().split())
tree[a].append((b, c))
tree[b].append((a, c))
def bfs(start):
dists = [-1] * (n+1)
dists[start] = 0
dq = deque([start]) # 노드번호
while dq:
cur = dq.popleft()
for nxt, cost in tree[cur]:
if dists[nxt] == -1:
dists[nxt] = dists[cur] + cost
dq.append(nxt)
return max((d, i) for i, d in enumerate(dists))
_, max_node = bfs(randint(1, n)) # 무작위로 하나 넣고
max_dist, _ = bfs(max_node) # 제일 멀리 있는 노드에서 다시 탐색
print(max_dist)
solve()⭐ 4. 백준 16197 (두 동전)
# 4. 알고(백트래킹): 백준 16197 (두 동전) - https://www.acmicpc.net/problem/16197
import sys
from itertools import product
from collections import deque
from io import StringIO
sys.stdin = StringIO('''6 2
..
..
..
o#
o#
##''')
input = sys.stdin.readline
def solve():
N, M = map(int, input().split())
board = [['e'] * (M + 2)]
for _ in range(N):
board.append(['e'] + list(input().rstrip()) + ['e'])
board.append(['e'] * (M + 2))
cur_coins = [] # [r1, c1, r2, c2]
for r, c in product(range(1, N+1), range(1, M + 1)):
if board[r][c] == 'o':
cur_coins.extend([r, c])
directions = [(0, -1), (0, +1), (-1, 0), (+1, 0)]
dq = deque([tuple(cur_coins + [0])]) # 거리 하나 추가.
visited = set(tuple(cur_coins))
while dq:
r1, c1, r2, c2, dist = dq.popleft()
if dist == 10: # 11번째 이동을 고려하기 시작할 때 종료.
break
dist += 1 # 단계 추가.
for dr, dc in directions:
nr1, nc1 = r1 + dr, c1 + dc
nr2, nc2 = r2 + dr, c2 + dc
nxt1 = board[nr1][nc1]
nxt2 = board[nr2][nc2]
drop1 = (nxt1 == 'e')
drop2 = (nxt2 == 'e')
if drop1 and drop2: # 둘다 낭떨어지면 패스
continue
if drop1 or drop2: # 하나만 낭 떨어지면 성공!
print(dist)
return
if nxt1 == "#": # 벽이면 다음 위치를 이전 위치로 복귀
nr1, nc1 = r1, c1
if nxt2 == "#":
nr2, nc2 = r2, c2
# 둘중 하나라도 이동할 수 있다면 (동전 겹치기 가능)
if (nr1, nc1, nr2, nc2) not in visited:
dq.append((nr1, nc1, nr2, nc2, dist)) # 다음 단계 추가.
visited.add((nr1, nc1, nr2, nc2))
print(-1)
solve()✏️ 5. SQL 식품분류별 가장 비싼 식품의 정보 조회하기
-- 5. SQL(Lv.4): 식품분류별 가장 비싼 식품의 정보 조회하기
-- https://school.programmers.co.kr/learn/courses/30/lessons/131116
WITH RP AS (
SELECT
CATEGORY,
PRICE,
PRODUCT_NAME,
RANK() OVER (
PARTITION BY
CATEGORY
ORDER BY
PRICE DESC
) RANKING
FROM
FOOD_PRODUCT
WHERE
CATEGORY IN ('과자', '국', '김치', '식용유')
)
SELECT
CATEGORY,
PRICE AS MAX_PRICE,
PRODUCT_NAME
FROM
RP
WHERE
RANKING = 1
ORDER BY
MAX_PRICE DESC;