Skip to content

Conversation

@Mingguriguri
Copy link
Collaborator

@Mingguriguri Mingguriguri commented Jun 22, 2025

푼 문제가 여러 개라면 아래 폼 형식 복사해서 넣어주시면 됩니다 :D

🌱WIL

이번 한 주의 소감을 작성해주세요!

  • 이번 주에는 BFS로 다양하게 탐색하는 방법을 배운 한 주였다. 발제 문제와 숨바꼭질 시리즈가 비슷하여 BFS를 더 연습해볼 수 있었던 것 같다. 문제마다 조건들이 있는데 해당 조건들에 어려워하지말고 분기 처리하면 된다는 것을 알게 되었다. 또 무엇보다 범위값을 잘 지정해야 한다.
  • 과제 문제에서는 0-1 BFS 유형을 알게 되었다. 0-1 BFS를 구현하기 위해서는 우선순위가 높은 것은 (deque 기준으로) appendleft로 우선 탐색할 수 있도록 해주어야 한다는 것을 알게 되었다.
  • 따로 푼 그리디 유형의 키패드 누르기 문제는 Level1이었지만 처음에 문제의 아이디어를 내기까지는 부끄럽지만 조금 시간이 걸렸다. 하지만 정말 단순하게 풀면 되는 문제였다.

🚀주간 목표 문제 수: 3개

푼 문제


백준 #14226. 이모티콘: 그래프 / 골드4

정리한 링크: (바로가기)

  • BFS 큐에는 (화면, 클립보드) 상태를 저장한다.
  • 각 상태에서 다음 세 가지 연산을 수행할 수 있다:
    1. 복사: (screen, screen)
    2. 붙여넣기: (screen + clipboard, clipboard) — 단, clipboard가 0이 아니어야 함
    3. 삭제: (screen - 1, clipboard)
  • 연산 수행 후 범위 확인 및 visited 체크를 통해 중복 방문을 방지한다.
  • 목표 개수인 S에 도달하면 해당 시간을 출력하고 종료한다.

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

🚩제출한 코드

import sys
from collections import deque
input = sys.stdin.readline

# 1. 입력 및 초기화
S = int(input())
MAX = 1001

# visited[screen][clipboard] = 해당 상태까지 걸린 시간
visited = [[-1] * MAX for _ in range(MAX)]
visited[1][0] = 0

queue = deque([(1, 0)]) # 화면 임티 개수, 클립보드 임티 개수

# 2. BFS 탐색
while queue:
    screen, clip = queue.popleft()

		# 3. 목표 달성 시 종료
    if screen == S:
        print(visited[screen][clip])
        break

    for i in range(3):
        if i == 0: # 복사 (화면 → 클립보드)
            new_screen, new_clipboard = screen, screen
        elif i == 1: # 붙여넣기 (클립보드 → 화면)
            new_screen, new_clipboard = screen + clip, clip
        else: # 삭제 (화면 - 1)
            new_screen, new_clipboard = screen - 1, clip

        if new_screen >= MAX or new_screen < 0 \
                or new_clipboard >= MAX or new_clipboard < 0 \
                or visited[new_screen][new_clipboard] != -1:
            continue

        visited[new_screen][new_clipboard] = visited[screen][clip] + 1
        queue.append((new_screen, new_clipboard))

💡TIL

배운 점이 있다면 입력해주세요

  • 지난 숨바꼭질2 문제와 비슷하게 최소 시간만 저장해야 할 것이 아닌 클립보드의 이모티콘 개수도 함께 저장해야 한다는 점에서 큰 아이디어가 비슷하다.
  • 범위를 MAX값을 1001로 지정해야 했는데 1000으로 지정한 점 등 잘못 지정한 게 많았기에 시간 내에 풀지 못해 아쉽다.

프로그래머스 #67256. 키패드 누르기: 그리디 / Level 1

정리한 링크: (바로가기)

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

  1. 키패드를 2차원 좌표로 매핑한다.
  2. 시작 위치는 왼손은 * , 오른손은 #이다.
  3. 순서대로 numbers 배열을 순회하면서:
    • 왼쪽 열 숫자 → L
    • 오른쪽 열 숫자 → R
    • 가운데 숫자 → 거리 비교 후 결정
  4. 각 경우에 따라 손 위치 갱신
  5. 누른 손을 문자열로 이어붙여 최종 반환

🚩제출한 코드

def solution(numbers, hand):
    answer = '' 
    pad = {'1':(0,0), '2':(0,1), '3':(0,2),
           '4':(1,0), '5':(1,1), '6':(1,2),
           '7':(2,0), '8':(2,1), '9':(2,2),
           '*':(3,0), '0':(3,1), '#':(3,2)
        }
    
    left = pad['*']
    right = pad['#']
    
    for num in numbers:
        # 왼손이 눌러야 하는 번호
        if num in (1, 4, 7):
            answer += 'L'
            left = pad[str(num)]
        # 오른손이 눌러야 하는 번호
        elif num in (3, 6, 9):
            answer += 'R'
            right = pad[str(num)]
        # 가운데 번호일 경우 (2, 5, 8, 0)
        else:

            # 해당 번호와 왼손 거리
            left_dist = abs(left[0] - pad[str(num)][0]) + abs(left[1] - pad[str(num)][1])
            # 해당 번호와 오른손 거리
            right_dist = abs(right[0] - pad[str(num)][0]) + abs(right[1] - pad[str(num)][1])
            
            # 더 가까운 거리 
            if left_dist < right_dist:
                answer += 'L'
                left = pad[str(num)]
            elif left_dist > right_dist:
                answer += 'R'
                right = pad[str(num)]
            # 왼손과 오른손 거리가 같을 경우
            else:
                if hand == 'right':
                    answer += 'R'
                    right = pad[str(num)]
                else:
                    answer += 'L'
                    left = pad[str(num)]
                    
        
    return answer

💡TIL

배운 점이 있다면 입력해주세요

  • 전형적인 그리디 & 구현 문제라고 생각한다. 그리디 전략을 기반으로 조건을 분기해 처리하면 된다. 처음에는 조건이 많아 어려워보였지만 규칙에 따라 풀이하면 되는 것 같다.
  • 핸드폰 키패드를 2차원 배열 좌표로 생각하면 된다는 아이디어가 핵심이었던 것 같다.

백준 #13549. 숨바꼭질3: 그래프 / 골드5

정리한 링크: (바로가기)

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

  1. 최대 좌표값인 100000까지 탐색할 수 있도록 범위 상수를 선언한다.
  2. visited 리스트를 1로 초기화하여 방문 여부와 시간을 동시에 기록한다.
  3. deque를 생성하고 시작 위치를 넣는다.
  4. 다음 규칙에 따라 큐를 순회하며 위치를 탐색한다:
    • 2 * x (순간이동): appendleft(), 시간 변화 없음
    • x ± 1 (걷기): append(), 시간 +1
  5. 목표 위치 K에 도달하면 종료한다.

🚩제출한 코드

import sys
from collections import deque
input = sys.stdin.readline

MAX = 100000
N, K = map(int, input().split())
visited = [-1] * (MAX + 1)

queue = deque()
queue.append(N)
visited[N] = 0

while queue:
    current = queue.popleft()

    # 순간이동 (0초) -> 큐 앞쪽에 넣기
    nx = current * 2
    if 0 <= nx <= MAX and visited[nx] == -1:
        visited[nx] = visited[current]
        queue.appendleft(nx)  # 핵심!

    # 걷는 경우 (+1, -1) -> 큐 뒤쪽에 넣기
    for nx in (current - 1, current + 1):
        if 0 <= nx <= MAX and visited[nx] == -1:
            visited[nx] = visited[current] + 1
            queue.append(nx)

print(visited[K])

💡TIL

배운 점이 있다면 입력해주세요

  • 이 문제가 숨바꼭질2와 다른 점은 “0초 이동”을 처리해야 한다는 것이다. 숨바꼭질2와 비슷하게 풀면 정확할 수 없다.
  • 이 문제를 통해서 0-1 BFS 유형을 알게 되었다. 0-1 BFS를 구현하기 위해서는 우선순위가 높은 것은 (deque 기준으로) appendleft로 우선 탐색할 수 있도록 해주어야 한다는 것을 알게 되었다.
  • heapq로도 풀이 가능하다.

@Mingguriguri Mingguriguri self-assigned this Jun 22, 2025
Copy link
Collaborator

@zaqquum zaqquum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이번 주도 문제 푸시느라 고생하셨습니다!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 이번 문제는 다른 풀이 참고해서 아래와 같이 for 문 탐색순서를 우선순위 따라 나열했는데 ** 0-1BFS** 란 풀이 유형이라는 건 처음 알았네요.

풀이 유형을 정의하고, 그에 대해 가독성 좋게 정리해주셔서 덕분에 이해가 잘 됐습니다!

for nx in (2*cx , cx-1 , cx+1 ) :

Copy link
Member

@YoonYn9915 YoonYn9915 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

숨바꼭질 3 문제 20분만에 푸셨다니 저보다 훨씬 빨리 정확하게 푸셨네요👍 👍

전 주 풀었던 숨바꼭질 1-2 문제가 많은 도움이 되었던 것 같습니다.

이번 한주도 고생많으셨어요~

Comment on lines +16 to +20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 이번 숨바꼭질 3문제는 숨바꼭질 2문제의 기본 뼈대에
0초에 일어나는 '순간이동' 동작은 다른 두 동작보다 우선순위가 높아(두 동작보다 빨리 끝나니까) 항상 순간이동한 좌표를 큐의 앞에 위치시키는 것이 핵심인 문제였습니다.
저는 순간이동을 처리할 때 그냥 for문안에 if문을 활용했는데 민정님처럼 appendleft()를 쓰거나 우선순위큐를 쓰면 더욱 가독성있는 코드가 될 것같습니다.

@Mingguriguri Mingguriguri merged commit 15b0786 into main Jun 22, 2025
@github-actions
Copy link

🔥2025-06 챌린지 진행 상황

👉 그래프

  • YoonYn9915: 3개 ❌
  • Mingguriguri: 4개 ❌

👉 구현

  • YoonYn9915: 1개 ❌
  • Mingguriguri: 1개 ❌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants