✅ 05 회차 모의고사 D-26일

🚨 강의영상링크


🚀 1차 코딩테스트 대비

  1. 백준 1063 (킹)
  2. 백준 2167 (2차원 배열의 합)
  3. 백준 9375 (패션왕 신해빈)
  4. 백준 15903 (카드 합체 놀이)
  5. SQL 고양이와 개는 몇 마리 있을까

👨‍🏫 COLAB

1차 풀이

⭐ 1. 백준 1063 (킹)

# 1. 알고(구현): 백준 1063 (킹) - https://www.acmicpc.net/problem/1063
import sys
 
from io import StringIO
sys.stdin = StringIO('''A8 B7 18
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB''')
 
input = sys.stdin.readline
 
N = 8
dirs = {
    'R': (0, +1),
    'L': (0, -1),
    'B': (+1, 0),
    'T': (-1, 0)
}
 
def pos_to_rc(str_val):
    row = N - int(str_val[1])
    col = ord(str_val[0]) - ord('A')
    return row, col
 
def rc_to_pos(row, col):
    temp = [chr(col + ord('A')), str(N - row)]
    return "".join(temp)
 
def solve():
 
    K, S, M = input().split()
 
    kr, kc = pos_to_rc(K)
    sr, sc = pos_to_rc(S)
 
    for _ in range(int(M)):
        moves = input().rstrip()
        nxt_kr, nxt_kc = kr, kc
 
        for m in moves:
            nxt_kr += dirs[m][0]
            nxt_kc += dirs[m][1]
 
        if 0 <= nxt_kr < N and 0 <= nxt_kc < N:
 
            # 이동위치에 스톤이 있을 때
            if (nxt_kr, nxt_kc) == (sr, sc):
                nxt_sr, nxt_sc = sr, sc
 
                for m in moves:
                    nxt_sr += dirs[m][0]
                    nxt_sc += dirs[m][1]
 
                if 0 <= nxt_sr < N and 0 <= nxt_sc < N:
                    kr, kc = nxt_kr, nxt_kc
                    sr, sc = nxt_sr, nxt_sc
 
            else:  # 이동위치에 스톤이 없을 때
                kr, kc = nxt_kr, nxt_kc
 
    print(rc_to_pos(kr, kc))  # 왕 출력
    print(rc_to_pos(sr, sc))  # 스톤 출력
 
solve()

⭐ 2. 백준 2167 (2차원 배열의 합)

# 2. 알고(수학): 백준 2167 (2차원 배열의 합) - https://www.acmicpc.net/problem/2167
import sys
 
from io import StringIO
sys.stdin = StringIO('''2 3
1 2 4
8 16 32
3
1 1 2 3
1 2 1 2
1 3 2 3''')
 
input = sys.stdin.readline
 
def solve():
 
    N, M, = map(int, input().split())
 
    nums = [tuple(map(int, input().split()))for _ in range(N)]
 
    # dp[i][j] (1, 1) 부터 (i, j)까지의 누적합
    dp = [[0] * (M + 1) for _ in range(N + 1)]
 
    for i in range(1, N+1):
        for j in range(1, M+1):
            dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + nums[i-1][j-1]
 
    result = []
    K = int(input())
    for _ in range(K):
        i, j, x, y = map(int, input().split())
        result.append(dp[x][y] - dp[i-1][y] - dp[x][j-1] + dp[i-1][j-1])
 
    print("\n".join(map(str, result)))
 
solve()

⭐ 3. 백준 9375 (패션왕 신해빈)

# 3. 알고(Map): 백준 9375 (패션왕 신해빈) - https://www.acmicpc.net/problem/9375
import sys
from collections import defaultdict
 
from io import StringIO
sys.stdin = StringIO('''2
3
hat headgear
sunglasses eyewear
turban headgear
3
mask face
sunglasses face
makeup face''')
 
input = sys.stdin.readline
 
def solve():
    n = int(input())
 
    count = defaultdict(int)
    for _ in range(n):
        type = input().split()[1]  # 타입만 받음
        count[type] += 1
 
    multi = 1  # 각 타입별 안입는 경우까지 포함해서 곱하기
    for type_count in count.values():
        multi *= (type_count + 1)
 
    print(multi - 1)  # 안입는 경우 제외
 
T = int(input())
for _ in range(T):
    solve()

⭐ 4. 백준 15903 (카드 합체 놀이)

# 4. 알고(그리디): 백준 15903 (카드 합체 놀이) - https://www.acmicpc.net/problem/15903
import sys
from heapq import heappop, heappush, heapify
 
from io import StringIO
sys.stdin = StringIO('''4 2
4 2 3 1''')
 
input = sys.stdin.readline
 
def solve():
 
    n, m = map(int, input().split())
    nums_pq = list(map(int, input().split()))
    heapify(nums_pq)
 
    for _ in range(m):
        a = heappop(nums_pq)
        b = heappop(nums_pq)
 
        sum_card = a + b
        heappush(nums_pq, sum_card)
        heappush(nums_pq, sum_card)
 
    print(sum(nums_pq))
 
solve()

✏️ 5. SQL 고양이와 개는 몇 마리 있을까

-- 5. SQL(Lv.2): 고양이와 개는 몇 마리 있을까 
-- https://school.programmers.co.kr/learn/courses/30/lessons/59040
SELECT
    ANIMAL_TYPE,
    COUNT(*) AS count
FROM
    ANIMAL_INS
WHERE
    ANIMAL_TYPE IN ('Cat', 'Dog')
GROUP BY
    ANIMAL_TYPE
ORDER BY
    ANIMAL_TYPE ASC;

🚀 2차 코딩테스트 대비

  1. 백준 3190 (뱀)
  2. 백준 2096 (내려가기)
  3. 백준 1991 (트리 순회)
  4. 백준 18428 (감시 피하기)
  5. SQL 저자 별 카테고리 별 매출액 집계하기

👨‍🏫 COLAB

2차 풀이

⭐ 1. 백준 3190 (뱀)

# 1. 알고(시뮬): 백준 3190 (뱀) - https://www.acmicpc.net/problem/3190
import sys
from collections import deque
 
from io import StringIO
sys.stdin = StringIO('''10
4
1 2
1 3
1 4
1 5
4
8 D
10 D
11 D
13 L''')
 
input = sys.stdin.readline
 
def solve():
 
    N = int(input())  # 테두리에 -1 돌리기.
    board = [[-1] * (N + 2) for _ in range(N + 2)]
    for r in range(1, N + 1):
        for c in range(1, N + 1):
            board[r][c] = 0
 
    K = int(input())  # 사과 (+1)
    for _ in range(K):
        r, c = map(int, input().split())
        board[r][c] = +1
 
    L = int(input())  # 방향전환 정보
    dirs = [(0, +1), (+1, 0), (0, -1), (-1, 0)]  # 오른쪽 부터 시계방향
    switchs = dict()
    for _ in range(L):
        time, direction = input().split()
        switchs[int(time)] = 1 if direction == 'D' else -1
 
    snake = deque([(1, 1)])       # 뱀의 몸 좌표
    board[1][1] = -1  # 초기 뱀의 몸
 
    time = 0        # 시간
    dir_idx = 0     # 진행방향
    while True:
        time += 1
        hr, hc = snake[-1]  # 현재 머리 위치
        dr, dc = dirs[dir_idx]
 
        nr, nc = hr + dr, hc + dc  # 다음 머리
        nxt_val = board[nr][nc]
        if nxt_val == -1:  # 벽 또는 몸이 나오면 종료
            break
 
        # 머리 늘리기
        snake.append((nr, nc))
        board[nr][nc] = -1
 
        if nxt_val != 1:  # 사과가 없을때만 꼬리 줄이기
            tr, tc = snake.popleft()
            board[tr][tc] = 0
 
        # 다음 방향 설정
        nxt_dir = switchs.get(time, 0)
        dir_idx = (dir_idx + nxt_dir) % 4
 
    print(time)
 
solve()

⭐ 2. 백준 2096 (내려가기)

# 2. 알고(DP): 백준 2096 (내려가기) - https://www.acmicpc.net/problem/2096
import sys
 
from io import StringIO
sys.stdin = StringIO('''3
1 2 3
4 5 6
4 9 0''')
 
input = sys.stdin.readline
 
def solve():
    N = int(input())
 
    max_dp = [0, 0, 0]
    min_dp = [0, 0, 0]
 
    for _ in range(N):
        a, b, c = map(int, input().split())
 
        max_dp = [
            a + max(max_dp[0], max_dp[1]),
            b + max(max_dp[0], max_dp[1], max_dp[2]),
            c + max(max_dp[1], max_dp[2])
        ]
 
        min_dp = [
            a + min(min_dp[0], min_dp[1]),
            b + min(min_dp[0], min_dp[1], min_dp[2]),
            c + min(min_dp[1], min_dp[2])
        ]
 
    print(max(max_dp), min(min_dp))
 
solve()

⭐ 3. 백준 1991 (트리 순회)

# 3. 알고(트리): 백준 1991 (트리 순회) - https://www.acmicpc.net/problem/1991
import sys
 
from io import StringIO
sys.stdin = StringIO('''7
A B C
B D .
C E F
E . .
F . G
D . .
G . .''')
 
input = sys.stdin.readline
 
def solve():
    N = int(input())
    tree = dict()
 
    for _ in range(N):
        root, left, right = input().split()
        tree[root] = [left, right]
 
    def search_node(root, type):
        if root == '.':
            return ""
 
        left, right = tree[root]
        l_node = search_node(left, type)
        r_node = search_node(right, type)
 
        orders = [
            root + l_node + r_node,  # 0: 전위
            l_node + root + r_node,  # 1: 중위
            l_node + r_node + root  # 2: 후위
        ]
 
        return orders[type]
 
    for type in range(3):
        print(search_node('A', type))
 
solve()

⭐ 4. 백준 18428 (감시 피하기)

# 4. 알고(최적화): 백준 18428 (감시 피하기) - https://www.acmicpc.net/problem/18428
import sys
from itertools import combinations
 
from io import StringIO
sys.stdin = StringIO('''5
X S X X T
T X S X X
X X X X X
X T X X X
X X T X X''')
 
input = sys.stdin.readline
 
def solve():
 
    N = int(input())
    board = [input().split() for _ in range(N)]
    dirs = [(0, +1), (0, -1), (+1, 0), (-1, 0)]
 
    teachers, emptys, students = [], [], []
    teacher_r, teacher_c = set(), set()
    students_r, students_c = set(), set()
 
    for r in range(N):
        for c in range(N):
            if board[r][c] == 'T':
                teachers.append((r, c))
                teacher_r.add(r)
                teacher_c.add(c)
            elif board[r][c] == 'S':
                students.append((r, c))
                students_r.add(r)
                students_c.add(c)
            else:
                emptys.append((r, c))
 
    emptys = [  # 선생님과 학생 r, c 와 관련 없으면 조사 제외
        (er, ec) for er, ec in emptys
        if (er in teacher_r and er in students_r)
        or (ec in teacher_c and ec in students_c)
    ]
 
    # 학생 발견되면 실패 (True), 발견 못하면 (False)
    def can_see_student(three_obs):
        for tr, tc in teachers:
            for dr, dc in dirs:
                nr, nc = tr + dr, tc + dc
                while 0 <= nr < N and 0 <= nc < N:
                    if (nr, nc) in three_obs:
                        break
                    if board[nr][nc] == 'S':
                        return True
                    if board[nr][nc] == 'T':
                        break
                    nr, nc = nr + dr, nc + dc
        return False
 
    if len(emptys) >= 3:
        for three_obs in combinations(emptys, 3):
            if not can_see_student(set(three_obs)):  # 학생 발견 못하면 바로 종료
                print("YES")
                return
    else:
        if not can_see_student(set(emptys)):  # 필터링 이후 조사대상이 3개보다 적으면,
            print("YES")
            return
 
    print("NO")
 
solve()

✏️ 5. SQL 저자 별 카테고리 별 매출액 집계하기

-- 5. SQL(Lv.4): 저자 별 카테고리 별 매출액 집계하기 
-- https://school.programmers.co.kr/learn/courses/30/lessons/144856
SELECT 
    A.AUTHOR_ID,
    A.AUTHOR_NAME,
    B.CATEGORY,
    SUM(SALES * PRICE) AS TOTAL_SALES
FROM 
    BOOK B
JOIN 
    AUTHOR A ON B.AUTHOR_ID = A.AUTHOR_ID
JOIN 
    BOOK_SALES S ON B.BOOK_ID = S.BOOK_ID
WHERE
    S.SALES_DATE LIKE '2022-01%'
GROUP BY
    A.AUTHOR_ID, A.AUTHOR_NAME, B.CATEGORY
ORDER BY 
    A.AUTHOR_ID ASC, B.CATEGORY DESC;