Skip to content

Conversation

@Mingguriguri
Copy link
Collaborator

🌱WIL

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

  • 이번 주에는 너무 바빠서 코테 문제 푸는 게 너무 빡셌다.. 시간 내는 게 중요한 것 같다. 또 TIL이나 내용 정리를 많이 못했는데 다음 주에는 제대로 할 수 있도록 시간을 꼭 내야겠다.
  • 계속 DP만 풀다가 오랜만에 구현, DFS 문제를 푸니까 헷갈리고 어려웠다.. 여러 문제를 골고루 푸는 것도 중요한 것 같다.

🚀주간 목표 문제 수: 4개

푼 문제


백준 #11660. 구간 합 구하기 5 : DP / 실버1

🚩플로우 (선택)

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

  1. 입력 처리:
    • 숫자 표 크기 N, 쿼리 수 M 입력받는다.
    • 숫자 표를 입력받아 grid 배열 생성한다.
  2. 누적합 테이블 계산:
    • prefix_sum[i][j]를 점화식을 통해 계산한다.
  3. 범위 합 계산:
    • 각 쿼리에 대해 주어진 범위를 누적합 공식으로 계산한다.

🚩제출한 코드

import sys
input = sys.stdin.readline

# 누적합 테이블 계산 함수
def get_prefix_sum(grid, N):
    prefix_sum = [[0] * (N+1) for _ in range(N+1)]
    for i in range(1, N+1):
        for j in range(1, N+1):
            prefix_sum[i][j] = (
                grid[i-1][j-1]
                + prefix_sum[i-1][j]
                + prefix_sum[i][j-1]
                - prefix_sum[i-1][j-1]
            )
    return prefix_sum

# 입력
N, M = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(N)]

# 누적합
prefix_sum = get_prefix_sum(grid, N)

# 범위 합 계산
for _ in range(M):
    x1, y1, x2, y2 = map(int, input().split())
    answer = (
        prefix_sum[x2][y2]
        - prefix_sum[x1-1][y2]
        - prefix_sum[x2][y1-1]
        + prefix_sum[x1-1][y1-1]
    )
    print(answer)

💡TIL

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

  • 기존 누적합 방식을 2차원에서 구간합을 구하는 방법을 배울 수 있는 문제였다.
  • 점화식 공식이 이해가 되지 않았지만, 겹치는 부분을 빼줘야 하는 원리를 하나씩 뜯어고치면서 이해하였다.
  • 복습이 필수!!

백준 #10844. 쉬운 계단 수: DP / 실버1

🚩제출한 코드

n = int(input())

num = [[0]*10 for _ in range(n+1)]
num[0] = [1,1,1,1,1,1,1,1,0] #0행에 들어가는 값들을 계단수의 경우의수로 초기화

for i in range(1,n+1):
    for j in range(10): #0일때, 9일때, 나머지인 경우를 점화식을 토대로 코드 작성
        if j == 0: 
            num[i][j] = num[i-1][1]
        elif j == 9:
            num[i][j] = num[i-1][8]
        else:
            num[i][j] = num[i-1][j-1] + num[i-1][j]

answer = sum(num[n]) % 100000000
print(answer)

💡TIL

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

  • DP의 점화식을 잘 세우는 것이 중요한 문제였다.

백준 #1914. 하노이탑: DP / 실버1

🚩제출한 코드

#하노이 함수
def hanoi_f(one, three, n):
    if n == 1:
        print(one,three)
        return
    
    hanoi_f(one, 6-one-three, n-1) #1단계 (1->2)
    print(one, three) #2단계 (마지막원반 1->3)
    hanoi_f(6-one-three, three, n-1) #3단계 (2->3)

#메인
n = int(input())
print(2**n-1)
if n <= 20:
    hanoi_f(1,3,n)

💡TIL

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

  • 문제를 풀 때, 바로 접근하지 말고, n=1, n=2, n=3, … 차례차례 나열해보며 규칙성을 파악해보자
  • 힌트를 듣고 마구잡이로 집어넣지 말고, 내 코드와 맥락이 맞는지 파악해보자
  • 공식의 경우, 미리 알고 있으면 좋겠지만, 직접 나열해보고 규칙을 찾아가는 식으로 해도 풀 수 있다.
  • 멘탈을 부여잡자

백준 #14500. 테트로미노: 구현 / 골드4

🚩플로우 (선택)

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

  1. 입력값 초기화
  • 종이 크기 N x M을 입력받는다.
  • 종이에 쓰인 숫자들을 이차원 배열 graph에 저장한다.
  • 방문 여부를 체크하는 visited 배열을 초기화한다.
  1. 탐색 방향 설정
  • 테트로미노의 모양을 만들기 위해 상하좌우 이동을 위한 방향 벡터 dx, dy를 설정한다.
  1. DFS 탐색: ㅗ 모양 제외
  • 모든 좌표에서 DFS를 시작한다.
  • DFS는 현재 위치에서 상하좌우로 이동하며 4칸을 방문한다.
  • 방문한 칸들의 합을 계산해 최댓값을 갱신한다.
  • 이미 방문한 칸은 다시 방문하지 않도록 체크하며, DFS가 끝난 후 복구한다.
  1. ㅗ 모양 탐색 (별도 처리)
  • DFS로 탐색할 수 없는 ㅗ 모양은 별도로 처리한다.
  • 모든 좌표를 중심으로 상하좌우 중 3개 방향을 선택해 합을 계산한다.
  • 범위를 벗어나거나 잘못된 위치일 경우 계산하지 않는다.
  1. 결과 출력
  • 모든 좌표에서 탐색이 끝난 후, 최댓값을 출력한다.

🚩제출한 코드

n, m = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(n)]
visited = [[False] * m for _ in range(n)]

# 방향 설정 (상, 하, 좌, 우)
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

# 최댓값 저장 변수
max_value = 0


# DFS 탐색 (ㅗ 모양 제외)
def dfs(x, y, count, total):
    global max_value
    # 테트로미노 4칸 채웠을 경우
    if count == 4:
        max_value = max(max_value, total)
        return

    # 상하좌우 탐색
    for i in range(4):
        nx, ny = x + dx[i], y + dy[i]
        # 범위 내에 있고, 방문하지 않은 경우
        if 0 <= nx < n and 0 <= ny < m and not visited[nx][ny]:
            visited[nx][ny] = True
            dfs(nx, ny, count + 1, total + graph[nx][ny])
            visited[nx][ny] = False  # 백트래킹


# ㅗ 모양 탐색
def check_t_shape(x, y):
    global max_value
    # 중심 기준 4방향 중 3개를 선택 (ㅗ, ㅜ, ㅏ, ㅓ)
    for i in range(4):
        total = graph[x][y]
        for j in range(3):  # 현재 제외한 3방향 탐색
            k = (i + j) % 4
            nx, ny = x + dx[k], y + dy[k]
            if 0 <= nx < n and 0 <= ny < m:
                total += graph[nx][ny]
            else:  # 범위를 벗어나면 ㅗ 모양이 성립하지 않음
                break
        else:  # 모든 3방향 탐색이 유효한 경우
            max_value = max(max_value, total)


# 모든 좌표에서 테트로미노 탐색
for i in range(n):
    for j in range(m):
        visited[i][j] = True
        dfs(i, j, 1, graph[i][j])  # DFS 시작
        visited[i][j] = False
        check_t_shape(i, j)  # ㅗ 모양 탐색

# 결과 출력
print(max_value)

💡TIL

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

  • 이 문제는 DFS 백트래킹과 시뮬레이션을 조합해야 했다.
  • 초기에는 DFS만으로 모든 테트로미노 모양을 탐색하려 했지만, ㅗ 모양이 제외된다는 점을 알게 되었다.
  • 탐색 범위 예외 처리가 중요했다. 종이 밖으로 벗어나는 경우를 조건문으로 철저히 검사해야 했다.
  • 백트래킹과 방문 처리를 통해 효율적으로 테트로미노를 배치할 수 있었다.
    이 문제를 통해 DFS 탐색과 예외 처리의 중요성을 다시 한번 깨달았다.

@Mingguriguri Mingguriguri self-assigned this Apr 7, 2025
@Mingguriguri Mingguriguri reopened this Apr 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant