✅ 18 회차 모의고사 D-13일

🚨 강의영상링크


🚀 1차 코딩테스트 대비

  1. 백준 11576 (Base Conversion)
  2. 백준 1850 (최대공약수)
  3. 백준 10546 (배부른 마라토너)
  4. 백준 2138 (전구와 스위치)
  5. SQL 고양이와 개는 몇 마리 있을까

👨‍🏫 COLAB

1차 풀이

⭐ 1. 백준 11576 (Base Conversion)

# 1. 알고(수학): 백준 11576 (Base Conversion) - https://www.acmicpc.net/problem/11576
import sys
 
from io import StringIO
sys.stdin = StringIO('''17 8
2
2 16''')
 
input = sys.stdin.readline
 
def solve():
    A, B = map(int, input().split())
    m = input()
    digits = map(int, input().split())
 
    a_to_ten = 0
    for digit in digits:  # 호너의 방법
        a_to_ten = a_to_ten * A + digit
 
    ten_to_b = []
    while a_to_ten > 0:
        ten_to_b.append(a_to_ten % B)
        a_to_ten //= B
 
    print(*reversed(ten_to_b) if ten_to_b else [0])
 
solve()

⭐ 2. 백준 1850 (최대공약수)

# 2. 알고(수학): 백준 1850 (최대공약수) - https://www.acmicpc.net/problem/1850
import sys
from math import gcd
 
from io import StringIO
sys.stdin = StringIO('''3 6''')
 
input = sys.stdin.readline
 
def solve():
 
    print('1'*gcd(*map(int, input().split())))
 
solve()

⭐ 3. 백준 10546 (배부른 마라토너)

# 3. 알고(Map): 백준 10546 (배부른 마라토너) - https://www.acmicpc.net/problem/10546
import sys
from collections import Counter
 
from io import StringIO
sys.stdin = StringIO('''5
marina
josipa
nikola
vinko
filipa
josipa
filipa
marina
nikola''')
 
input = sys.stdin.readline
 
def solve():
    N = int(input())
    attend = Counter(input().rstrip() for _ in range(N))
 
    for _ in range(N-1):
        name = input().rstrip()
        if attend[name] == 1:
            del attend[name]
        else:
            attend[name] -= 1
 
    print(*attend)
 
solve()

⭐ 4. 백준 2138 (전구와 스위치)

# 4. 알고(그리디): 백준 2138 (전구와 스위치) - https://www.acmicpc.net/problem/2138
import sys
 
from io import StringIO
sys.stdin = StringIO('''3
000
010''')
 
input = sys.stdin.readline
 
def solve():
 
    N = int(input())
    base = list(map(lambda x: x == '1', input().rstrip()))
    goal = list(map(lambda x: x == '1', input().rstrip()))
 
    def push(i, arr):
        for j in [i-1, i, i+1]:
            if 0 <= j < N:
                arr[j] = not arr[j]
 
    def simulate(press_first):
        arr = base[:]
        push_cnt = 0
 
        if press_first:
            push(0, arr)
            push_cnt += 1
 
        for i in range(N-1):
            if arr[i] != goal[i]:       # 맨 앞부터 조사
                push(i + 1, arr)        # 다르면 버튼 누르기
                push_cnt += 1
 
        is_possible = arr[N-1] == goal[N-1]     # 마지막 값 조사.
        return push_cnt if is_possible else float('inf')
 
    result = min(simulate(True), simulate(False))
    print(result if result != float('inf') else -1)
 
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 
GROUP BY
    ANIMAL_TYPE
ORDER BY
    ANIMAL_TYPE;

🚀 2차 코딩테스트 대비

  1. 백준 17822 (원판 돌리기)
  2. 백준 17070 (파이프 옮기기 1)
  3. 백준 1922 (네트워크 연결)
  4. 백준 1799 (비숍)
  5. SQL 오프라인/온라인 판매 데이터 통합하기

👨‍🏫 COLAB

2차 풀이

⭐ 1. 백준 17822 (원판 돌리기)

# 1. 알고(시뮬): 백준 17822 (원판 돌리기) - https://www.acmicpc.net/problem/17822
import sys
from collections import deque
from itertools import product
 
from io import StringIO
sys.stdin = StringIO('''4 6 3
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
2 1 4
3 0 1
2 1 2''')
 
input = sys.stdin.readline
 
def solve():
    N, M, T = map(int, input().split())
    directions = [(0, +1), (+1, 0)]
 
    circles = list()
    total_sum = 0
    alive_cnt = N * M
 
    for _ in range(N):
        dq = deque(map(int, input().split()))
        circles.append(dq)
        total_sum += sum(dq)
 
    for _ in range(T):
        x, d, k = map(int, input().split())
        dir = +1 if d == 0 else -1   # 0 시계 방향, 숫자도 시계방향
 
        for i in range(x, N+1, x):
            circles[i-1].rotate(k*dir)  # 인덱스 조정
 
        will_delete = set()
        for r, c in product(range(N), range(M)):
            val = circles[r][c]
            if val == 0:
                continue
 
            for dr, dc in directions:
                nr, nc = r + dr, (c + dc) % M    # col 만 순환
                if nr < N and circles[nr][nc] == val:
                    will_delete.add((r, c))      # 두 방향 만 조사함으로 넣어줘야 함
                    will_delete.add((nr, nc))
 
        if will_delete:
            for r, c in will_delete:
                total_sum -= circles[r][c]
                circles[r][c] = 0
                alive_cnt -= 1
 
        elif alive_cnt > 0:
            avg_nums = total_sum / alive_cnt
            for r, c in product(range(N), range(M)):
                val = circles[r][c]
                if val == 0:
                    continue
 
                if val > avg_nums:
                    circles[r][c] -= 1
                    total_sum -= 1
                elif val < avg_nums:
                    circles[r][c] += 1
                    total_sum += 1
 
    print(total_sum)
 
solve()

⭐ 2. 백준 17070 (파이프 옮기기 1)

# 2. 알고(DP): 백준 17070 (파이프 옮기기 1) - https://www.acmicpc.net/problem/17070
import sys
from itertools import product
 
from io import StringIO
sys.stdin = StringIO('''6
0 0 0 0 0 0
0 1 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0''')
 
input = sys.stdin.readline
 
def solve():
    N = int(input())
    board = [list(map(int, input().split())) for _ in range(N)]
 
    # 각각 가로, 세로, 대각
    hori = [[0] * N for _ in range(N)]
    vert = [[0] * N for _ in range(N)]
    diag = [[0] * N for _ in range(N)]
 
    hori[0][1] = 1
 
    for c in range(2, N):       # 첫 번째 칸은 가로로 만 이동해서 머리 위치 가능.
        if board[0][c] == 1:    # 벽 나오면 바로 중지.
            break
        else:
            hori[0][c] = 1
 
    for r, c in product(range(1, N), repeat=2):
 
        if board[r][c] == 1:   # 벽이면 머리가 놓일 수 없음
            continue
 
        # 최종적으로 가로(hori)
        hori[r][c] = hori[r][c-1] + diag[r][c-1]
 
        # 최종적으로 세로(vert)
        vert[r][c] = vert[r-1][c] + diag[r-1][c]
 
        # 대각(diag)으로 놓이려면 왼쪽, 위에 도 벽이 없어야 함
        if board[r][c-1] == 0 and board[r-1][c] == 0:
            diag[r][c] = hori[r-1][c-1] + vert[r-1][c-1] + diag[r-1][c-1]
 
    print(hori[N-1][N-1] + vert[N-1][N-1] + diag[N-1][N-1])
 
solve()

⭐ 3. 백준 1922 (네트워크 연결)

# 3. 알고(그래프): 백준 1922 (네트워크 연결) - https://www.acmicpc.net/problem/1922
import sys
 
from io import StringIO
sys.stdin = StringIO('''6
9
1 2 5
1 3 4
2 3 2
2 4 7
3 4 6
3 5 11
4 5 3
4 6 8
5 6 8''')
 
input = sys.stdin.readline
 
def solve():
 
    N = int(input())
    M = int(input())
 
    parent = list(range(N))
    edges = [tuple(map(int, input().split())) for _ in range(M)]
    edges.sort(key=lambda x: x[2])
 
    def find(v):
        if parent[v] != v:
            parent[v] = find(parent[v])
        return parent[v]
 
    def union(ra, rb):
        if ra > rb:
            ra, rb = rb, ra
        parent[rb] = ra
 
    total_cost = 0
    union_cnt = 0
    
    for a, b, cost in edges:
        ra = find(a-1)
        rb = find(b-1)
 
        if ra != rb:
            union(ra, rb)
            total_cost += cost
            union_cnt += 1
 
            if union_cnt > N:
                break
 
    print(total_cost)
 
solve()

⭐ 4. 백준 1799 (비숍)

# 4. 알고(백트래킹): 백준 1799 (비숍) - https://www.acmicpc.net/problem/1799
import sys
from itertools import product
 
from io import StringIO
sys.stdin = StringIO('''5
1 1 0 1 1
0 1 0 0 0
1 0 1 0 1
1 0 0 0 0
1 0 1 1 1''')
 
input = sys.stdin.readline
 
def solve():
 
    N = int(input())
    board = [list(input().split()) for _ in range(N)]
 
    # 비숍이 대각선 방향에 있나요?
    left_right = [False] * (2*N - 1)
    right_left = [False] * (2*N - 1)
 
    blacks = []
    whites = []
    for r, c in product(range(N), repeat=2):
        if board[r][c] == '1':
            if (r + c) % 2 == 0:
                blacks.append((r, c))
            else:
                whites.append((r, c))
 
    def put_bishop(r, c, state):
        left_right[r+c] = state
        right_left[r+(N-1-c)] = state
 
    def can_put(r, c):
        first = not left_right[r+c]     # 비숍이 없으면 True
        second = not right_left[r+(N-1-c)]
        return first and second
 
    def solve_color(emptys):
        max_cnt = 0
 
        def dfs(index, bishop_cnt):
            nonlocal max_cnt
 
            if index == len(emptys):
                max_cnt = max(max_cnt, bishop_cnt)
                return
 
            r, c = emptys[index]
 
            if can_put(r, c):
                put_bishop(r, c, True)
                dfs(index + 1, bishop_cnt + 1)
                put_bishop(r, c, False)
 
            dfs(index + 1, bishop_cnt)
 
        dfs(0, 0)
        return max_cnt
 
    print(solve_color(whites) + solve_color(blacks))
 
solve()

✏️ 5. SQL 오프라인/온라인 판매 데이터 통합하기

-- 5. SQL(Lv.4): 오프라인/온라인 판매 데이터 통합하기 
-- https://school.programmers.co.kr/learn/courses/30/lessons/131537
WITH 
    ON_OFF AS (
        SELECT
            DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE,
            PRODUCT_ID,
            USER_ID,
            SALES_AMOUNT
        FROM
            ONLINE_SALE
        WHERE
            SALES_DATE LIKE '2022-03-%'
        
        UNION ALL
        
        SELECT
            DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE,
            PRODUCT_ID,
            NULL AS USER_ID,
            SALES_AMOUNT
        FROM
            OFFLINE_SALE
        WHERE
            SALES_DATE LIKE '2022-03-%'
    )
SELECT
    SALES_DATE,
    PRODUCT_ID,
    USER_ID,
    SALES_AMOUNT
FROM 
    ON_OFF
ORDER BY
    SALES_DATE ASC,
    PRODUCT_ID ASC, 
    USER_ID ASC;