Skip to content

Conversation

@Mingguriguri
Copy link
Collaborator

🌱WIL

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

  • 이번 한 주는 새로 시작한 부트캠프에 적응하느라 많은 문제를 풀지는 못했다...
  • 발제와 과제 문제로 BFS+구현 문제를 풀었고, 다른 문제로는 java로 힙 유형 문제를 풀이해보았다. BFS 구현 문제의 경우, 큰 틀은 다 동일한 것 같다. 다만 방향이라거나, 맵이 이동한다거나 추가적인 조건을 다루는 것이 어려운 부분인 것 같다. #16509 장군 문제도 방향이 8가지나 되어 이동하는 걸 고려하는 것이 가장 헷갈렸던 부분이었다. #11559. Puyo Puyo 는 중력을 처리하는 부분이 막막했다. Puyo가 터지게 되면 밑으로 내려오도로 하기 위해서 반복적으로 교환하며 풀이하는 부분이 인상적이었다. 나의 경우, 이 부분에서 막혀서 다른 분들의 정답을 보고 풀이를 이어가게 되었다.
  • Java로 풀이한 프로그래머스 고득점 kit - 더 맵게 문제의 경우, Java에서 Heap을 구현하기 위해서는 PriorityQueue를 사용하면 된다는 것을 알게 되었다.

🚀주간 목표 문제 수: 3개

푼 문제


백준 #16509. 장군: 그래프 / 골드5

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

🚩플로우 (선택)

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

  1. 입력으로 상의 위치와 왕의 위치를 받는다.
  2. 장기판의 범위는 10x9이며, 방문 여부를 저장할 배열을 만든다.
  3. 상의 이동 방향을 8가지로 정의한다. (3단계 이동 경로로 표현)
  4. BFS 큐에 상의 시작 위치를 넣고 탐색을 시작한다.
  5. 현재 위치에서 8방향 이동을 시도하며, 이동 경로의 중간 두 칸에 왕이 있는지 확인한다.
  6. 왕이 중간 경로에 없다면 다음 칸으로 이동하고 큐에 추가한다.
  7. 상이 왕이 있는 위치에 도달하면 해당까지의 이동 횟수를 반환한다.
  8. BFS 종료 시까지 왕에게 도달하지 못했다면 -1을 출력한다.

🚩제출한 코드

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

# 1. 상과 왕 초기 위치
s_r, s_c = map(int, input().split())  # 상의 위치
k_r, k_c = map(int, input().split())  # 왕의 위치

# 장기판 (10x9)
grid = [[0 for _ in range(9)] for _ in range(10)]
visited = [[False for _ in range(9)] for _ in range(10)]

# 8가지 이동 경로
directions = [
    # 상
    ((-1, 0), (-1, 1), (-1, 1)),    # 오른쪽 위
    ((-1, 0), (-1, -1), (-1, -1)),  # 왼쪽 위
    # 하
    ((1, 0), (1, 1), (1, 1)),       # 오른쪽 아래
    ((1, 0), (1, -1), (1, -1)),     # 왼쪽 아래
    # 좌
    ((0, -1), (-1, -1), (-1, -1)),  # 왼쪽 위
    ((0, -1), (1, -1), (1, -1)),    # 왼쪽 아래
    # 우
    ((0, 1), (-1, 1), (-1, 1)),     # 오른쪽 위
    ((0, 1), (1, 1), (1, 1))        # 오른쪽 아래
]


def bfs():
    queue = deque([(s_r, s_c)])  # 상 위치부터 시작
		
    while queue:
        r, c = queue.popleft()

        # 왕에게 도달한 경우
        if (r, c) == (k_r, k_c):
            return grid[r][c]

        for d1, d2, d3 in directions:
            nr1, nc1 = r + d1[0], c + d1[1]
            nr2, nc2 = nr1 + d2[0], nc1 + d2[1]
            nr3, nc3 = nr2 + d3[0], nc2 + d3[1]
            
            if (0 <= nr3 < 10 and 0 <= nc3 < 9) and not visited[nr3][nc3]:
                if (nr1, nc1) == (k_r, k_c) or (nr2, nc2) == (k_r, k_c):
                    # 경로에 왕이 있다면 못 감
                    continue
                    
                visited[nr3][nc3] = True
                grid[nr3][nc3] += grid[r][c] + 1
                queue.append((nr3, nc3))

    return -1 # 도달 불가


print(bfs())

💡TIL

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

  • 방향을 설정하는 것이 헷갈렸다.
  • 이전에 풀었던 토마토 문제나 나이트 이동 문제를 BFS로 풀어본 경험이 있어 비교적 수월하게 구현할 수 있었다.

백준 #11559. Puyo Puyo: 그래프 / 골드4

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

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?
전체 로직은 while True 반복문으로 구성되며, 한 턴에서 아래 단계를 수행한다:

  • visited 배열을 초기화한다.
  • 전체 필드를 순회하며, 아직 방문하지 않은 뿌요를 기준으로 BFS 탐색을 한다.
  • 같은 색의 뿌요가 4개 이상인 그룹은 삭제하고 pang = True로 설정한다.
  • pang이 참이면 블록을 아래로 내리고 combo += 1
  • 더 이상 터질 뿌요가 없으면 종료한다.

🚩제출한 코드

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

FIELD_X = 12
FIELD_Y = 6

# 1. 입력
field = [list(input().strip()) for _ in range(FIELD_X)]

directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
combo = 0

# 상하좌우로 동일한 블록을 탐색해 해당 좌표들을 가진 리스트 반환
def bfs(x, y):
    queue = deque([(x, y)])
    color = field[x][y]
    visited[x][y] = True
    same_blocks = [(x, y)] # 같은 블록의 좌표 리스트

    while queue:
        x, y = queue.popleft()
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if (0 <= nx < FIELD_X and 0 <= ny < FIELD_Y) and \
                field[nx][ny] == color and not visited[nx][ny]:
                queue.append((nx, ny))
                visited[nx][ny] = True
                same_blocks.append((nx, ny))

    return same_blocks


# 동일한 블록 제거
def delete(same_blocks):
    for x, y in same_blocks:
        field[x][y] = '.'


# 반복문 돌면서 위에서 아래로 블록 내리기
def down():
    for y in range(FIELD_Y):
        for x in range(10, -1, -1):
            for k in range(FIELD_X - 1, x, -1):
                if field[x][y] != '.' and field[k][y] == '.':
                    field[k][y] = field[x][y]
                    field[x][y] = '.'


while True:
    pang = False
    visited = [[False for _ in range(FIELD_Y)] for _ in range(FIELD_X)]

    for i in range(FIELD_X):
        for j in range(FIELD_Y):
            if field[i][j] != '.' and not visited[i][j]:
                same_blocks = bfs(i, j)

                # 동일한 블록이 4개 이상일 경우 터트리기
                if len(same_blocks) >= 4:
                    pang = True
                    delete(same_blocks)


    # 터뜨린 블록이 있으면 밑으로 내리기
    if pang:
        down()
        combo += 1
    else:
        # 더이상 터뜨릴 게 없다면 종료
        break

print(combo)

💡TIL

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

  • 처음에는 중력 처리 부분이 막막했다. 아래로 내리는 로직을 떠올리기 어려워 다른 분의 코드를 참고했다.
  • down() 함수에서 위에서 아래로 내려오도록 반복적으로 교환하는 방식이 인상 깊었다.
  • BFS 탐색은 익숙했지만, 탐색 + 삭제 + 중력 적용을 반복적으로 수행하는 시뮬레이션 문제는 생각보다 까다로웠다.
  • 뿌요뿌요와 같이 실제 게임 로직을 그대로 구현하는 문제는 구현력이 굉장히 중요하다는 것을 다시 느꼈다.

프로그래머스 #42626. 더맵게: 힙 / Level2

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

🚩플로우 (선택)

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

  • 배열을 PriorityQueue에 담는다.
  • while문을 통해:
    • 첫 번째 요소가 K 이상이면 바로 정답 반환.
    • 그렇지 않다면 최소 두 개를 꺼내서 새 음식 생성 → 큐에 다시 삽입.
  • 큐에 하나만 남고 그것도 K 미만이면 1 반환.

🚩제출한 코드

import java.util.Arrays;
import java.util.PriorityQueue;

class Solution {
    public int solution(int[] scoville, int K) {
        int answer = 0;
        Arrays.sort(scoville);
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();

        // scoville 배열을 minHeap으로 옮기기
        for (int s: scoville) {
            minHeap.offer(s);
        }
        
        // minHeap의 크기가 1보다 작아질 때까지 반복
        while (minHeap.size() > 1) {
		        // 이미 K보다 크다면 바로 return
            if (minHeap.peek() >= K) {
                return answer;
            }
            int a = minHeap.poll();
            int b = minHeap.poll();
            minHeap.offer(a + b * 2);
            answer++;
        }
        
        // 마지막 하나도 확인해야 한다.
        if (minHeap.peek() >= K) {
            return answer;
        }
       
        return -1;
    }
}

💡TIL

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

  • 파이썬에서는 deque를 이용하여 쉽게 구현할 수 있던 부분을 Java로 접근하니 어떤 프레임워크를 써야 할 지 감이 오지 않았다.
  • Java Heap이라고 검색하니 “PriorityQueue” 컬렉션이 나오게 되었다. 이 자료구조를 활용하여 풀이하니 쉽게 접근할 수 있었다.
  • PriorityQueue 자료형에서 사용하는 요소는 offer, peek, poll이 있다.
  • 이 문제는 효율성을 통과하기 위해서는 PriorityQueue를 써야만 하는 유형이었다.

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문으로 바로 윗 칸의 내용과 swap 하여 빈공간을 점점 위로 올리는 식으로 동작하는 것이 인상적이였습니다.
저는 아래 부터 stack으로 뿌요뿌요만 축척한 후 다시 아래부터 재배치하는 식으로 구현했는데 다른 알고리즘으로 동작 할 수 있네요


def refine_field(x) : # 중간 빈자리
  stack = deque()
  #1.아레=> 위로 스택에 뿌요뿌요 순서대로 축척하기 
  for ny in range(11, -1,-1):
    if field[ny][x] != ".":
      stack.append(field[ny][x])
  for ny in range(11, -1, -1) :
    if stack : 
       field[ny][x] = stack.popleft()
    else :
      field[ny][x] = "."

@Mingguriguri Mingguriguri merged commit 6de432d into main Jun 7, 2025
@github-actions
Copy link

github-actions bot commented Jun 7, 2025

🔥2025-05 챌린지 진행 상황

👉 그래프

  • Mingguriguri: 2개 ❌

👉 구현

  • Mingguriguri: 0개 ❌

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.

3 participants