<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yunni_.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 30 Apr 2025 14:55:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. yunni_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/yunni_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[백준 1663 / Python] XYZ 문자열]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-1663-Python-XYZ-%EB%AC%B8%EC%9E%90%EC%97%B4</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-1663-Python-XYZ-%EB%AC%B8%EC%9E%90%EC%97%B4</guid>
            <pubDate>Wed, 30 Apr 2025 14:55:17 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1663">XYZ 문자열</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>DP</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<blockquote>
<p>단계가 4이상일 때 문자열이 만들어지는 규칙
    ➡️ <code>3번째 전</code> 문자열 + <code>2번째 전</code> 문자열</p>
</blockquote>
<ul>
<li><p>1번 문제 </p>
<ul>
<li>문자열의 길이를 담는 <code>dp</code> 배열 생성</li>
<li><code>dp[i] = dp[i-3] + dp[i-2]</code></li>
</ul>
</li>
<li><p>2번 문제</p>
<ul>
<li>각 문자의 개수를 담는 <code>cnt</code> 배열 생성</li>
<li><code>0-2</code>까지 3번 반복하며 <code>cnt[i][j] = cnt[i-3][j] + cnt[i-2][j]</code></li>
</ul>
</li>
<li><p>3번 문제</p>
<ul>
<li>3단계까지 기저 문자열을 담는 <code>base</code> 배열 생성</li>
<li><code>find(idx, depth)</code>함수로 재귀적으로 <code>이분탐색</code><ul>
<li><code>왼쪽</code>에서 온 경우: <code>idx &lt;= depth[i-3]</code><ul>
<li><code>오른쪽</code>에서 온 경우: <code>idx &gt; depth[i-3]</code></li>
<li>depth가 <code>3이하</code>이면, <code>base</code>에서 찾아서 반환</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="📄-코드">📄 코드</h4>
<pre><code class="language-python">t = int(input())
n = int(input())

dp = [0] * 101
cnt = [[0, 0, 0] for _ in range(101)]
base = [&quot;&quot;, &quot;X&quot;, &quot;YZ&quot;, &quot;ZX&quot;]

dp[1] = 1
dp[2] = 2
dp[3] = 2
cnt[1] = [1, 0, 0]
cnt[2] = [0, 1, 1]
cnt[3] = [1, 0, 1]

# 이분탐색으로 기저문자 찾기
def find(idx, depth):
    if depth &lt;= 3: # 기저문자 반환
        return base[depth][idx - 1]
    if dp[depth - 3] &gt;= idx: # 왼쪽에서 옴
        return find(idx, depth - 3)
    else: # 오른쪽에서 옴
        return find(idx - dp[depth - 3], depth - 2)

for i in range(4, n + 1):
    dp[i] = dp[i - 3] + dp[i - 2]
    for j in range(3):
        cnt[i][j] = cnt[i - 3][j] + cnt[i - 2][j]

if t == 1:
    print(dp[n])
elif t == 2:
    k = int(input())
    print(find(k, n))
else:
    ch = input()
    print(cnt[n][ord(ch) - ord(&#39;X&#39;)])</code></pre>
<ul>
<li>시간복잡도: <code>O(N)</code></li>
</ul>
<p>참고: <a href="https://ongveloper.tistory.com/311">https://ongveloper.tistory.com/311</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 2470 / Python] 두 용액]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-2470-Python-%EB%91%90-%EC%9A%A9%EC%95%A1</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-2470-Python-%EB%91%90-%EC%9A%A9%EC%95%A1</guid>
            <pubDate>Thu, 24 Apr 2025 07:17:09 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/2470">두 용액</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>투포인터</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li>배열 오름차순 <code>정렬</code></li>
<li>초기 포인터로 배열의 <code>양 끝점</code> 가리키고, 초기값(<code>answer</code>)을 두 지점의 합으로 설정</li>
<li>두 값 더해주며 절댓값이 <code>answer</code>보다 작으면 갱신</li>
<li>두 값의 합이 <code>음수</code>이면 <code>start+1</code></li>
<li>두 값의 합이 <code>양수</code>이면 <code>end-1</code></li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<pre><code class="language-python">import sys
input = sys.stdin.readline

n = int(input())
arr = list(map(int, input().split()))
arr.sort() # O(NlogN)

# 양 끝 지점 포인팅
start, end = 0, n - 1
ans_val = [arr[0], arr[1]]
answer = abs(arr[0] + arr[1])

# 투포인터 탐색: O(N)
while start &lt; end:
    two_val = arr[start] + arr[end]
    if abs(two_val) &lt; answer:
        answer = abs(arr[start] + arr[end])
        ans_val = [arr[start], arr[end]]
        if answer == 0:
            break
    # 합이 0보다 작으면 시작점 증가
    if two_val &lt; 0:
        start += 1
    # 0보다 크면 끝점 감소
    else:
        end -= 1

# 오름차순 정렬 후 출력
ans_val.sort()
print(*ans_val)</code></pre>
<ul>
<li>시간복잡도: <code>O(NlogN)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 / Python] 양과 늑대]]></title>
            <link>https://velog.io/@yunni_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Python-%EC%96%91%EA%B3%BC-%EB%8A%91%EB%8C%80</link>
            <guid>https://velog.io/@yunni_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Python-%EC%96%91%EA%B3%BC-%EB%8A%91%EB%8C%80</guid>
            <pubDate>Wed, 23 Apr 2025 14:07:27 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/92343">양과 늑대</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>DFS</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ul>
<li>아래 두 가지 조건만 확인해주면서 <code>DFS</code> 진행하면 됨<ol>
<li>양의 개수 &gt; 늑대의 개수</li>
<li>부모 노드 방문 &amp; 자식 노드 미방문</li>
</ol>
</li>
</ul>
<h4 id="📄-코드">📄 코드</h4>
<pre><code class="language-python">def solution(info, edges):
    answer = []
    visited = [False] * len(info)

    def dfs(sheep, wolf):
        if sheep &gt; wolf:
            answer.append(sheep)
        else:
            return
        for p, c in edges:
            # 부모 노드 방문한 적 있으면서 자식 노드 처음 방문
            if visited[p] and not visited[c]:
                visited[c] = True
                if info[c] == 0:
                    dfs(sheep + 1, wolf)
                else:
                    dfs(sheep, wolf + 1)
                visited[c] = False # 백트래킹

    visited[0] = True
    dfs(1, 0)

    return max(answer)</code></pre>
<ul>
<li>시간복잡도: <code>O(2^N)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 9663 / Python] N-Queen]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-9663-Python-N-Queen</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-9663-Python-N-Queen</guid>
            <pubDate>Wed, 23 Apr 2025 07:30:46 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/9663">N-Queen</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>백트래킹</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<blockquote>
<p><code>1차원 배열</code>로도 구현 가능</p>
</blockquote>
<ol>
<li><code>row[x]=i</code>는 <code>(x행, i열)</code>에 퀸이 놓여있다는 뜻</li>
<li>유망성 판단은 현재 행인 <code>x</code>전까지 놓여있는 퀸 확인
 1) <code>같은 열</code>에 놓여있는지 확인
 2) <code>대각선</code>에 놓여있는지 확인: <code>행 차이==열 차이</code></li>
<li>행이 <code>n</code>에 도달했을때 답 추가</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<pre><code class="language-python">n = int(input())

answer = 0
row = [0] * n

def is_promising(x):
    for i in range(x):
        if row[i] == row[x] or abs(i - x) == abs(row[i] - row[x]):
            return False
    return True

def dfs(x):
    global answer
    if x == n:
        answer += 1
        return
    for i in range(n):
        row[x] = i # x행 i열
        if is_promising(x):
            dfs(x + 1)

dfs(0)     
print(answer)</code></pre>
<ul>
<li>시간복잡도: <code>O(N!)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 2292 / Python] 벌집]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-2292-Python-%EB%B2%8C%EC%A7%91</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-2292-Python-%EB%B2%8C%EC%A7%91</guid>
            <pubDate>Wed, 23 Apr 2025 06:24:33 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/2292">벌집</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>수학</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ul>
<li>아래와 같은 규칙으로 테두리가 생김<ul>
<li>끝 숫자를 보면 6, 12, 18, 24..씩 <code>6의 배수</code>만큼 <code>차이</code>가 증가<pre><code>1
2-7
8-19
20-37
38-61</code></pre></li>
</ul>
</li>
<li>끝 숫자가 <code>n보다 작을</code> 때까지 배열에 넣고 배열의 <code>길이</code> 출력</li>
</ul>
<h4 id="📄-코드">📄 코드</h4>
<pre><code class="language-python">&quot;&quot;&quot;
1
2-7
8-19
20-37
38-61
&quot;&quot;&quot;

n = int(input())
edge = [1]
diff = 0
while edge[-1] &lt; n:
    diff += 6
    edge.append(edge[-1] + diff)

print(len(edge))</code></pre>
<ul>
<li>시간복잡도: $O(\sqrt N)$</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 1094 / Python] 막대기]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-1094-Python-%EB%A7%89%EB%8C%80%EA%B8%B0</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-1094-Python-%EB%A7%89%EB%8C%80%EA%B8%B0</guid>
            <pubDate>Tue, 22 Apr 2025 16:20:54 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1094">막대기</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>수학</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<blockquote>
<p>문제해석: <code>64, 32, 16, 8, 4, 2, 1</code> 길이의 막대 몇 개를 가지고 만들 수 있는지</p>
</blockquote>
<ol>
<li><code>현재 막대(n)</code>이 <code>x</code>보다 크다면 <code>반</code>으로 나누기</li>
<li>그렇지 않다면 <code>x</code>에서 <code>n</code> 빼주고 <code>갯수</code> 증가</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<pre><code class="language-python">x = int(input())

n = 64
answer = 0

while x &gt; 0:
    if n &gt; x:
        n //= 2
    else:
        x -= n
        answer += 1

print(answer)</code></pre>
<ul>
<li>시간복잡도: <code>O(1)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 1018 / Python] 체스판 다시 칠하기]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-1018-Python-%EC%B2%B4%EC%8A%A4%ED%8C%90-%EB%8B%A4%EC%8B%9C-%EC%B9%A0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-1018-Python-%EC%B2%B4%EC%8A%A4%ED%8C%90-%EB%8B%A4%EC%8B%9C-%EC%B9%A0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 22 Apr 2025 15:40:15 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1018">체스판 다시 칠하기</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>브루트포스</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li><code>8*8</code> 크기의 체스판 슬라이싱<ul>
<li>시작점 범위는 <code>행(0, n-7)</code>, <code>열(0, m-7)</code></li>
<li>체스판 범위는 <code>(현재행, 현재행+8)</code>, <code>(현재열, 현재열+8)</code></li>
</ul>
</li>
<li>최소 변경 횟수 구하기<ul>
<li>두 패턴 만들기 -&gt; <code>(행+열)==짝수(W)</code> 일때와 <code>(행+열)==홀수(B)</code> 일 때</li>
<li>위 두 패턴별로 짝수/홀수마다 <code>일치하지 않는 칸</code> 개수 카운트</li>
</ul>
</li>
<li>두 패턴별 카운트한 것 중 <code>최솟값</code>을 정답으로 출력</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<pre><code class="language-python">import sys
input = sys.stdin.readline

n, m = map(int, input().split())
board = [list(input().rstrip()) for _ in range(n)]
answer = int(1e9)

# 두 패턴 중 최소 변환 갯수를 선택
def calculate_min(arr):
    ans1, ans2 = 0, 0
    for i in range(8):
        for j in range(8):
            if (i + j) % 2 == 0: # 짝수
                if arr[i][j] != &#39;W&#39;:
                    ans1 += 1
                else:
                    ans2 += 1
            else: # 홀수
                if arr[i][j] != &#39;B&#39;:
                    ans1 += 1
                else:
                    ans2 += 1
    return min(ans1, ans2)

# 8*8크기의 체스판 슬라이싱
for i in range(n - 7):
    for j in range(m - 7):
        sliced = []
        for x in range(i, i + 8):
            row = &quot;&quot;
            for y in range(j, j + 8):
                row += board[x][y]
            sliced.append(row)
        answer = min(answer, calculate_min(sliced))

print(answer)
</code></pre>
<ul>
<li>시간복잡도: <code>O(NM)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 4920 / Python] 테트리스 게임]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-4920-Python-%ED%85%8C%ED%8A%B8%EB%A6%AC%EC%8A%A4-%EA%B2%8C%EC%9E%84</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-4920-Python-%ED%85%8C%ED%8A%B8%EB%A6%AC%EC%8A%A4-%EA%B2%8C%EC%9E%84</guid>
            <pubDate>Tue, 22 Apr 2025 09:27:06 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/4920">테트리스 게임</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>구현</li>
<li>브루트포스</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<blockquote>
<p>테트리스를 뒤집을 수 없고 <code>회전</code>만 가능함에 주의❗️</p>
</blockquote>
<ol>
<li>가능한 테트리스 모양 모두 <code>shapes</code>에 저장</li>
<li>격자판 모두 탐색하며 테트리스 모양 놓기<ul>
<li>테트리스 셀 중 하나라도 격자판 <code>범위</code> 벗어나면 pass</li>
<li>격자판 범위 내라면 값 계산후 <code>최댓값</code> 갱신</li>
</ul>
</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">import sys
input = sys.stdin.readline
</code></pre>
</li>
</ul>
<p>shapes = [
    # 1
    [(0,0), (0,1), (0,2), (0,3)],
    [(0,0), (1,0), (2,0), (3,0)],</p>
<pre><code># 2
[(0,0), (0,1), (1,1), (1,2)],
[(0,1), (1,0), (1,1), (2,0)],

# 3
[(0,1), (1,1), (2,0), (2,1)],
[(0,0), (0,1), (0,2), (1,2)],
[(0,0), (0,1), (1,0), (2,0)],
[(0,0), (1,0), (1,1), (1,2)],

# 4
[(0,0), (0,1), (0,2), (1,1)],
[(0,1), (1,0), (1,1), (2,1)],
[(0,1), (1,0), (1,1), (1,2)],
[(0,0), (1,0), (1,1), (2,0)]

# 5
[(0,0), (0,1), (1,0), (1,1)],</code></pre><p>]</p>
<p>T = 1
while True:
    answer = -int(1e9)
    n = int(input())
    if n == 0:
        break
    arr = [list(map(int, input().split())) for _ in range(n)]
    for i in range(n):
        for j in range(n):
            for s in shapes:
                total = 0
                for dx, dy in s: 
                    # 범위 벗어나면 해당 모양 pass
                    if not (0 &lt;= i + dx &lt; n and 0 &lt;= j + dy &lt; n):
                        break
                    total += arr[i + dx][j + dy]
                else:
                    answer = max(answer, total)</p>
<pre><code>print(f&quot;{T}. {answer}&quot;)
T += 1</code></pre><p>```</p>
<ul>
<li>시간복잡도: <code>O(N^)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 23289 / Python] 온풍기 안녕!]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-23289-Python-%EC%98%A8%ED%92%8D%EA%B8%B0-%EC%95%88%EB%85%95</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-23289-Python-%EC%98%A8%ED%92%8D%EA%B8%B0-%EC%95%88%EB%85%95</guid>
            <pubDate>Tue, 22 Apr 2025 07:58:10 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/23289">온풍기 안녕!</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>구현</li>
<li>시뮬레이션</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<blockquote>
<ol>
<li>벽을 <code>set</code>에 양방향으로 저장하기</li>
<li>바깥쪽 온도 1씩 감소할때 <code>모서리 중복</code>되지 않도록 주의하기</li>
</ol>
</blockquote>
<ol>
<li><p>격자 정보 받을 때 행, 열 인덱스 <code>-1</code>씩, 정보칸은 정보 따로 저장 후 <code>0</code>으로 변환</p>
</li>
<li><p>히터 순회하며 온도 상승
 1) <code>queue</code>를 이용해서 한 라인 진행될때마다 상승 온도 1씩 감소시키며 진행
 2) 벽이 있으면 확산 중지</p>
<ul>
<li><p>마찬가지로 오, 왼, 위, 아래 각각 케이스 나눠서 확인</p>
<p>3) 상승 온도가 0이면 확산 멈추기</p>
</li>
</ul>
</li>
<li><p>온도 조절</p>
<ul>
<li>새로운 2차원 배열에 변화값 저장 후 이후 한꺼번에 적용</li>
</ul>
</li>
<li><p>바깥쪽 온도 감소시키고 초콜릿 먹기</p>
<ul>
<li>모서리 중복 주의</li>
</ul>
</li>
<li><p>조사칸들 순회하며 k이상인지 조사
1) 모두 만족하면 성능테스트 끝내기
2) 아니면 계속 진행</p>
</li>
<li><p>정답 출력</p>
</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">import sys
from collections import deque
input = sys.stdin.readline
</code></pre>
</li>
</ul>
<p>r, c, k = map(int, input().split())
arr = []
heaters = set()
inspection = set()</p>
<p>dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]</p>
<p>for i in range(r):
    row = list(map(int, input().split()))
    arr.append(row)
    for j in range(c):
        if row[j] == 5:
            inspection.add((i, j))
            arr[i][j] = 0 # 정보 얻었으면 해당 칸 0으로 교체
        elif row[j] != 5 and row[j] != 0:
            heaters.add((i, j, row[j] - 1))
            arr[i][j] = 0 # 정보 얻었으면 해당 칸 0으로 교체</p>
<p>w = int(input())
walls = set() # 벽 정보
for _ in range(w):
    x, y, t = map(int, input().split())
    x -= 1
    y -= 1
    if t == 0:
        # 양방향으로 저장
        walls.add((x, y, x - 1, y))
        walls.add((x - 1, y, x, y))
    else:
        walls.add((x, y, x, y + 1))
        walls.add((x, y + 1, x, y))</p>
<h1 id="해당-칸이-격자판-범위-내인지-검사">해당 칸이 격자판 범위 내인지 검사</h1>
<p>def in_range(x, y):
    return 0 &lt;= x &lt; r and 0 &lt;= y &lt; c</p>
<h1 id="두-칸-사이에-벽이-있는지-검사">두 칸 사이에 벽이 있는지 검사</h1>
<p>def check_wall(x, y, nx, ny, dir):
    if dir == 0: # 오
        if nx == x: # 바로 오
            return (x, y, x, y + 1) in walls
        elif nx == x - 1: # 위쪽 오
            return (x, y, x - 1, y) in walls or (x - 1, y, x - 1, y + 1) in walls
        elif nx == x + 1: # 아래쪽 오
            return (x, y, x + 1, y) in walls or (x + 1, y, x + 1, y + 1) in walls
    elif dir == 1: # 왼
        if nx == x: # 바로 왼
            return (x, y, x, y - 1) in walls
        elif nx == x - 1: # 위쪽 왼
            return (x, y, x - 1, y) in walls or (x - 1, y, x - 1, y - 1) in walls
        elif nx == x + 1: # 아래쪽 오
            return (x, y, x + 1, y) in walls or (x + 1, y, x + 1, y - 1) in walls
    elif dir == 2: # 위
        if ny == y: # 바로 위
            return (x, y, x - 1, y) in walls
        elif ny == y - 1: # 왼쪽 위
            return (x, y, x, y - 1) in walls or (x, y - 1, x - 1, y - 1) in walls
        elif ny == y + 1: # 오른쪽 위
            return (x, y, x, y + 1) in walls or (x, y + 1, x - 1, y + 1) in walls
    elif dir == 3: # 아래
        if ny == y: # 바로 아래
            return (x, y, x + 1, y) in walls
        elif ny == y - 1: # 왼쪽 아래
            return (x, y, x, y - 1) in walls or (x, y - 1, x + 1, y - 1) in walls
        elif ny == y + 1: # 오른쪽 아래
            return (x, y, x, y + 1) in walls or (x, y + 1, x + 1, y + 1) in walls
    return False</p>
<h1 id="온도-상승">온도 상승</h1>
<p>def windows(x, y, dir):
    x = x + dx[dir]
    y = y + dy[dir]
    temper = 5
    arr[x][y] += temper
    visited[x][y] = True
    q = deque([(x, y, temper - 1)])
    while q:
        if temper == 0:
            break
        x, y, temper = q.popleft()
        if dir == 0: # 오
            for i in [x - 1, x, x + 1]:
                if in_range(i, y + 1) and not visited[i][y + 1]:
                    if check_wall(x, y, i, y + 1, dir) == False: # 벽 체크
                        arr[i][y + 1] += temper
                        visited[i][y + 1] = True
                        q.append((i, y + 1, temper - 1))
        elif dir == 1: # 왼
            for i in [x - 1, x, x + 1]:
                if in_range(i, y - 1) and not visited[i][y - 1]:
                    if check_wall(x, y, i, y - 1, dir) == False: # 벽 체크
                        arr[i][y - 1] += temper
                        visited[i][y - 1] = True
                        q.append((i, y - 1, temper - 1))
        elif dir == 2: # 위
            for j in [y - 1, y, y + 1]:
                if in_range(x - 1, j) and not visited[x - 1][j]:
                    if check_wall(x, y, x - 1, j, dir) == False: # 벽 체크
                        arr[x - 1][j] += temper
                        visited[x - 1][j] = True
                        q.append((x - 1, j, temper - 1))
        elif dir == 3: # 아래
            for j in [y - 1, y, y + 1]:
                if in_range(x + 1, j) and not visited[x + 1][j]:
                    if check_wall(x, y, x + 1, j, dir) == False: # 벽 체크
                        arr[x + 1][j] += temper
                        visited[x + 1][j] = True
                        q.append((x + 1, j, temper - 1))</p>
<h1 id="온도-조절">온도 조절</h1>
<p>def control():
    total_temper = [[0] * c for _ in range(r)] # 최종 온도 변화값
    # 총 온도 변화 계산
    for x in range(r):
        for y in range(c):
            for i in range(4):
                nx = x + dx[i]
                ny = y + dy[i]
                if in_range(nx, ny) and arr[x][y] &gt; arr[nx][ny]:
                    if check_wall(x, y, nx, ny, i) == False:
                        diff = (arr[x][y] - arr[nx][ny]) // 4
                        total_temper[x][y] -= diff
                        total_temper[nx][ny] += diff
    # 온도 적용
    for i in range(r):
        for j in range(c):
            arr[i][j] += total_temper[i][j]
            if arr[i][j] &lt; 0:
                arr[i][j] = 0</p>
<h1 id="바깥쪽-온도-1씩-감소">바깥쪽 온도 1씩 감소</h1>
<p>def lower_side():
    for i in [0, r - 1]:
        for j in range(c):
            if arr[i][j] - 1 &gt;= 0:
                arr[i][j] -= 1
    # 모서리 중복 처리 안되도록 주의!!
    for j in [0, c - 1]:
        for i in range(1, r - 1):
            if arr[i][j] - 1 &gt;= 0:
                arr[i][j] -= 1</p>
<h1 id="조사-칸들-k이상인지-검사">조사 칸들 k이상인지 검사</h1>
<p>def check_inspection():
    for x, y in inspection:
        if arr[x][y] &lt; k:
            return False
    return True</p>
<p>chocolate = 0</p>
<h1 id="성능테스트-하나씩-진행">성능테스트 하나씩 진행</h1>
<p>while True:
    # 1. 히터마다 온도 상승시키기
    for x, y, dir in heaters:
        # 한 히터에 대해서는 중복 방문x
        visited = [[False] * c for _ in range(r)]
        windows(x, y, dir)</p>
<pre><code># 2. 온도 조절
control()

# 3. 바깥쪽 온도 감소
lower_side()

# 4. 초콜릿 먹기
chocolate += 1

# 5. 조사
if check_inspection():
    break

# 100이 넘어가면 멈추기
if chocolate &gt; 100:
    break</code></pre><h1 id="정답-출력">정답 출력</h1>
<p>print(chocolate)</p>
<pre><code>- 최적화 버전: 바람 확산 칸들 사전에 계산해서 딕셔너리에 저장
```python
import sys
from collections import deque
input = sys.stdin.readline

# 방향: 오른쪽, 왼쪽, 위, 아래
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]

r, c, k = map(int, input().split())
arr = [[0] * c for _ in range(r)]
heaters = []
inspection = set()

for i in range(r):
    row = list(map(int, input().split()))
    for j in range(c):
        if row[j] == 5:
            inspection.add((i, j))
        elif row[j] != 0:
            heaters.append((i, j, row[j] - 1))  # (x, y, dir)

# 벽 정보 입력 및 세트화 (빠른 탐색 가능)
w = int(input())
walls = set()
for _ in range(w):
    x, y, t = map(int, input().split())
    x -= 1
    y -= 1
    if t == 0:  # 위쪽 벽
        walls.add((x, y, x - 1, y))
        walls.add((x - 1, y, x, y))
    else:  # 오른쪽 벽
        walls.add((x, y, x, y + 1))
        walls.add((x, y + 1, x, y))

def in_range(x, y):
    return 0 &lt;= x &lt; r and 0 &lt;= y &lt; c

def wall_blocked(x1, y1, x2, y2):
    return (x1, y1, x2, y2) in walls

# 히터 바람 영향 좌표 캐싱
heater_wind_map = dict()

def precompute_heater_wind():
    for x, y, dir in heaters:
        visited = [[False] * c for _ in range(r)]
        nx, ny = x + dx[dir], y + dy[dir]
        if not in_range(nx, ny):
            continue

        q = deque()
        q.append((nx, ny, 5))
        visited[nx][ny] = True
        temp_list = [(nx, ny, 5)]

        while q:
            cx, cy, val = q.popleft()
            if val == 1:
                continue

            if dir in (0, 1):  # 오 or 왼
                dlist = [(-1, dy[dir]), (0, dy[dir]), (1, dy[dir])]
            else:  # 위 or 아래
                dlist = [(dx[dir], -1), (dx[dir], 0), (dx[dir], 1)]

            for dx_, dy_ in dlist:
                nx, ny = cx + dx_, cy + dy_
                if not in_range(nx, ny) or visited[nx][ny]:
                    continue
                # 벽이 가로막는지 체크
                bx, by = cx, cy
                if wall_blocked(bx, by, bx + dx_, by) or wall_blocked(bx + dx_, by, bx + dx_, by + dy_):
                    continue
                visited[nx][ny] = True
                temp_list.append((nx, ny, val - 1))
                q.append((nx, ny, val - 1))

        heater_wind_map[(x, y, dir)] = temp_list

def apply_wind():
    for key in heater_wind_map:
        for x, y, val in heater_wind_map[key]:
            arr[x][y] += val

def control():
    delta = [[0]*c for _ in range(r)]
    for x in range(r):
        for y in range(c):
            for d in range(4):
                nx, ny = x + dx[d], y + dy[d]
                if not in_range(nx, ny):
                    continue
                if wall_blocked(x, y, nx, ny):
                    continue
                if arr[x][y] &gt; arr[nx][ny]:
                    diff = (arr[x][y] - arr[nx][ny]) // 4
                    delta[x][y] -= diff
                    delta[nx][ny] += diff
    for i in range(r):
        for j in range(c):
            arr[i][j] += delta[i][j]

def lower_side():
    for i in [0, r-1]:
        for j in range(c):
            if arr[i][j] &gt; 0:
                arr[i][j] -= 1
    for j in [0, c-1]:
        for i in range(1, r-1):
            if arr[i][j] &gt; 0:
                arr[i][j] -= 1

def check_inspection():
    for x, y in inspection:
        if arr[x][y] &lt; k:
            return False
    return True

# 사전 계산
precompute_heater_wind()

# 시뮬레이션 시작
choco = 0
while choco &lt;= 100:
    apply_wind()       # 1. 히터 바람 영향 적용
    control()          # 2. 온도 조절
    lower_side()       # 3. 외곽 감소
    choco += 1         # 4. 초콜릿 먹기
    if check_inspection():  # 5. 검사
        break

print(choco)</code></pre><ul>
<li>시간복잡도: <code>O(RC)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 2294 / Python] 동전 2]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-2294-Python-%EB%8F%99%EC%A0%84-2</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-2294-Python-%EB%8F%99%EC%A0%84-2</guid>
            <pubDate>Tue, 22 Apr 2025 05:11:04 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/2294">동전 2</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>DP</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li>dp 배열을 k+1만큼 생성 후 모두 최댓값으로 초기화</li>
<li>dp[0]=0으로 초기화</li>
<li>가치를 <code>1</code>부터 탐색하며 이전 가치에서 동전을 <code>하나</code> 추가했을때 <code>최솟값</code> 찾아서 갱신</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">import sys
input = sys.stdin.readline
</code></pre>
</li>
</ul>
<p>n, k = map(int, input().split())
coins = []
dp = [10001] * (k + 1)
dp[0] = 0</p>
<p>for _ in range(n):
    coin = int(input())
    coins.append(coin)</p>
<p>for i in range(1, k + 1):
    for coin in coins:
        if i - coin &gt;= 0:
            dp[i] = min(dp[i], dp[i - coin] + 1)</p>
<p>if dp[k] == 10001:
    print(-1)
else:
    print(dp[k])</p>
<p>```</p>
<ul>
<li>시간복잡도: <code>O(NK)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 20002 / Python] 사과나무]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-20002-Python-%EC%82%AC%EA%B3%BC%EB%82%98%EB%AC%B4</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-20002-Python-%EC%82%AC%EA%B3%BC%EB%82%98%EB%AC%B4</guid>
            <pubDate>Mon, 21 Apr 2025 15:11:56 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/20002">사과나무</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>누적합</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li>2차원 배열 범위를 <code>(N+1)(N+1)</code>로 늘리고 첫 행, 첫 열을 모두 <code>0</code>으로 채우기</li>
<li>2차원 <code>누적합</code> 생성</li>
<li>2차원 배열을 순회하며 <code>시작점</code>을 설정하고, <code>K를 1부터 N까지</code> 늘리면서 <code>누적합 계산</code></li>
<li><code>최댓값</code>으로 정답 갱신</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">import sys
input = sys.stdin.readline
</code></pre>
</li>
</ul>
<p>n = int(input())</p>
<h1 id="첫-행-첫-열-0으로-패딩주기">첫 행, 첫 열 0으로 패딩주기</h1>
<p>arr = [[0] * (n + 1)]
for _ in range(n):
    arr.append([0]+list(map(int, input().split())))</p>
<h1 id="누적합-생성">누적합 생성</h1>
<p>prefix_sum = [[0] * (n + 1) for _ in range(n + 1)]</p>
<p>for i in range(1, n + 1):
    prefix_sum[i][1] = prefix_sum[i - 1][1] + arr[i][1]</p>
<p>for j in range(1, n + 1):
    prefix_sum[1][j] = prefix_sum[1][j - 1] + arr[1][j]</p>
<p>for i in range(2, n + 1):
    for j in range(2, n + 1):
        prefix_sum[i][j] = arr[i][j] + prefix_sum[i - 1][j] + prefix_sum[i][j - 1] - prefix_sum[i - 1][j - 1]</p>
<p>answer = -int(1e9)</p>
<p>for i in range(1, n + 1):
    for j in range(1, n + 1):
        # 정사각형 사이즈 1부터 늘리기
        for k in range(1, n + 1):
            x1, y1, x2, y2 = i, j, i + k - 1, j + k - 1
            # 범위 벗어나면 무시
            if x2 &gt; n or y2 &gt; n:
                continue
            # 누적합 계산
            total = prefix_sum[x2][y2] - prefix_sum[x1 - 1][y2] - prefix_sum[x2][y1 - 1] + prefix_sum[x1 - 1][y1 - 1]
            # 최댓값 갱신
            answer = max(answer, total)</p>
<h1 id="정답-출력">정답 출력</h1>
<p>print(answer)</p>
<p>```</p>
<ul>
<li>시간복잡도: <code>O(N^3)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 7682 / Python] 틱택토]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-7682-Python-%ED%8B%B1%ED%83%9D%ED%86%A0</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-7682-Python-%ED%8B%B1%ED%83%9D%ED%86%A0</guid>
            <pubDate>Mon, 21 Apr 2025 09:40:27 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/7682">틱택토</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>dfs</li>
<li>백트래킹</li>
<li>완탐</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li><code>dfs/백트래킹</code>으로 가능한 말의 조합 모두 생성<ul>
<li><code>turn</code>을 인자로 줘서 <code>홀수</code>면 <code>X</code>, <code>짝수</code>면 <code>O</code>로 놓기</li>
<li><code>turn</code>이 <code>10</code>이면 더 이상 놓을 수 없으므로 <code>종료</code></li>
<li>한 말로 <code>3칸</code> 연결되면 (2) <code>종료</code></li>
</ul>
</li>
<li><code>3칸</code> 연결 확인<ul>
<li><code>가로</code> 확인</li>
<li>전치 행렬로 변환해서 <code>세로</code> 확인</li>
<li>두 <code>대각선</code> 확인</li>
</ul>
</li>
<li><code>set</code>에 가능한 모든 <code>조합 저장</code> 후 입력 받을 때마다 set에 있는지 <code>확인</code></li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python"># 한 말이 3칸 이어지는지
def check_line(c):
  # 가로 체크
  for row in board:
      if row.count(c) == 3:
          return True
  transform_board = [list(row) for row in zip(*board)]
  transform_board = tuple(map(tuple, transform_board))
  # 세로 체크
  for row in transform_board:
      if row.count(c) == 3:
          return True
  # 대각선 체크
  for i, j in zip(range(3), range(3)):
      if board[i][j] != c:
          break
  else:
      return True
  # 반대쪽 대각선 체크
  for i, j in zip(range(3), range(2, -1, -1)):
      if board[i][j] != c:
          break
  else:
      return True
</code></pre>
</li>
</ul>
<h1 id="가능한-모든-경우-탐색">가능한 모든 경우 탐색</h1>
<p>def dfs(turn):
    # 3칸 연결 체크
    if check_line(&#39;O&#39;) or check_line(&#39;X&#39;):
        forms.add(tuple(map(tuple, board)))
        return
    # 꽉 채웠는지 체크
    if turn == 10:
        forms.add(tuple(map(tuple, board)))
        return
    for i in range(3):
        for j in range(3):
            if board[i][j] == &#39;.&#39;:
                board[i][j] = &#39;X&#39; if turn % 2 == 1 else &#39;O&#39; # 턴이 홀수일 땐 X, 짝수일 땐 O
                dfs(turn + 1)
                board[i][j] = &#39;.&#39;</p>
<p>board = [[&#39;.&#39;] * 3 for _ in range(3)]
forms = set() # 2차원 배열을 튜플로 변환 필요</p>
<p>dfs(1) # 첫 번째 턴부터 진행</p>
<p>while True:
    s = input()
    if s == &quot;end&quot;:
        break</p>
<pre><code># 3*3 튜플 격자판 생성
arr = []
for i in range(0, 8, 3):
    arr.append(list(s[i:i+3]))
arr = tuple(map(tuple, arr))

# 가능한 조합에 없으면 invalid, 있으면 valid
if arr not in forms:
    print(&quot;invalid&quot;)
else:
    print(&quot;valid&quot;)</code></pre><p>```</p>
<ul>
<li>시간복잡도: <code>O(9!)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 11779 / Python] 최소비용 구하기 2]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-11779-Python-%EC%B5%9C%EC%86%8C%EB%B9%84%EC%9A%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-2</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-11779-Python-%EC%B5%9C%EC%86%8C%EB%B9%84%EC%9A%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-2</guid>
            <pubDate>Wed, 16 Apr 2025 04:18:21 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/11779">최소비용 구하기 2</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>다익스트라</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li>노드에 도착하기 직전 노드를 저장하는 <code>prev</code> 배열 생성</li>
<li>다익스트라 진행하면서 <code>prev[현재노드] = 이전노드</code> 저장</li>
<li>다익스트라 진행 완료 후, 도착지점부터 출발지점까지 <code>역추적</code>하며 경로 생성</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">import heapq
</code></pre>
</li>
</ul>
<p>n = int(input())
m = int(input())
graph = [[] for _ in range(n + 1)]
for _ in range(m):
    a, b, c = map(int, input().split())
    graph[a].append((b, c))
start, end = map(int, input().split())</p>
<p>distance = [int(1e9)] * (n + 1)
prev = [0] * (n + 1) # 이전 경로 기록</p>
<p>def dijkstra(start):
    q = []
    heapq.heappush(q, (0, start))
    distance[start] = 0
    while q:
        dist, now = heapq.heappop(q)
        if dist &gt; distance[now]:
            continue
        for i in graph[now]:
            cost = dist + i[1]
            if cost &lt; distance[i[0]]:
                distance[i[0]] = cost
                prev[i[0]] = now
                heapq.heappush(q, (cost, i[0]))</p>
<p>dijkstra(start)
print(distance[end])</p>
<h1 id="최단경로-역추적">최단경로 역추적</h1>
<p>path = []
cur = end
while cur != start:
    path.append(cur)
    cur = prev[cur]
path.append(start)
path.reverse()
print(len(path))
answer =  &quot; &quot;.join(map(str,path))
print(answer)
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 11660 / Python] 구간 합 구하기 5]]></title>
            <link>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-11660-Python-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-5</link>
            <guid>https://velog.io/@yunni_/%EB%B0%B1%EC%A4%80-11660-Python-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-5</guid>
            <pubDate>Tue, 15 Apr 2025 16:47:06 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/11660">구간 합 구하기 5</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>누적합</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<blockquote>
<p>2차원 누적합 문제</p>
</blockquote>
<ol>
<li><code>arr</code>와 누적합인 <code>prefix_sum</code> 2차원 배열의 첫 행, 첫 열을 모두 <code>0으로 패딩</code>을 넣어주는 것이 중요❗️</li>
<li>누적합 생성 점화식<ul>
<li><code>prefix_sum[i][j]</code> = <code>arr[i][j]</code> + <code>prefix_sum[i-1][j]</code> + <code>prefix_sum[i][j-1]</code> - <code>prefix_sum[i-1][j-1]</code></li>
</ul>
</li>
<li>구간별(x1, y1, x2, y2) 합 구하는 점화식<ul>
<li><code>sum</code> = <code>prefix_sum[x2][y2]</code> - <code>prefix_sum[x1-1][y2]</code> - <code>prefix_sum[x2][y1-1]</code> + <code>prefix_sum[x1-1][y1-1]</code></li>
</ul>
</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">n, m = map(int, input().split())
arr = [[0] * (n + 1)] # 첫 행, 첫 열을 모두 0으로 채우고 시작
for _ in range(n):
  arr.append([0] + list(map(int, input().split())))
</code></pre>
</li>
</ul>
<p>rectangles = []
for _ in range(m):
    a, b, c, d = map(int, input().split())
    rectangles.append((a, b, c, d))</p>
<h1 id="누적합-생성-역시-첫-행-첫-열은-모두-0으로">누적합 생성: 역시 첫 행, 첫 열은 모두 0으로</h1>
<p>prefix_sum = [[0] * (n + 1) for _ in range(n + 1)]</p>
<h1 id="가로-쭉-채우기">가로 쭉 채우기</h1>
<p>sum = 0
for i in range(1, n + 1):
    sum += arr[i][1]
    prefix_sum[i][1] = sum</p>
<h1 id="세로-쭉-채우기">세로 쭉 채우기</h1>
<p>sum = 0
for j in range(1, n + 1):
    sum += arr[1][j]
    prefix_sum[1][j] = sum</p>
<h1 id="누적합-생성">누적합 생성</h1>
<p>for i in range(1, n + 1):
    for j in range(1, n + 1):
        prefix_sum[i][j] = arr[i][j] + prefix_sum[i - 1][j] + prefix_sum[i][j - 1] - prefix_sum[i - 1][j - 1]        </p>
<h1 id="구간별-누적합-구하기">구간별 누적합 구하기</h1>
<p>for x1, y1, x2, y2 in rectangles:
    ans = prefix_sum[x2][y2] - prefix_sum[x1-1][y2] - prefix_sum[x2][y1 - 1] + prefix_sum[x1 - 1][y1 - 1]
    print(ans)
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스/Python] 방의 개수]]></title>
            <link>https://velog.io/@yunni_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Python-%EB%B0%A9%EC%9D%98-%EA%B0%9C%EC%88%98</link>
            <guid>https://velog.io/@yunni_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Python-%EB%B0%A9%EC%9D%98-%EA%B0%9C%EC%88%98</guid>
            <pubDate>Tue, 15 Apr 2025 15:30:32 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/49190">방의 개수</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>그래프</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<blockquote>
<p><strong>고려해야 할 문제</strong>
    1. 같은 점을 다른 경로를 통해 돌아오는 것이 아니라 그냥 같은 길을 <code>왕복</code>해서 돌아올 수 있음
        -&gt; <code>간선을 따로</code> 저장
    2. 대각선이 <code>교차</code>할 때
        -&gt; 간선의 길이를 0.5로 설정하여 한 방향으로 <code>두 번</code> 나아가기</p>
</blockquote>
<ol>
<li>방문한 점을 저장하는<code>visited_nodes</code>와 지나온 간선을 저장하는 <code>visited_edges</code> 생성<ul>
<li>점을 그냥 왕복해서 돌아올 수 있으므로 점만으로는 방의 개수를 판별할 수 없음</li>
<li><code>visited_edges</code>는 무방향 간선 그래프로 설정</li>
</ul>
</li>
<li>대각선 교차를 고려하여 한 방향으로 나아가는 것을 총 <code>2번</code> 진행</li>
<li>나아갈 점이 <code>노드 셋에 있고</code>, 나아갈 간선이 <code>간선 셋에 없으면</code> 정답에 1 추가</li>
<li>노드 셋과 간선 셋에 새로운 점과 경로 <code>추가</code></li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li><p>Python</p>
<pre><code class="language-python">def solution(arrows):
  answer = 0
  dx = [-1, -1, 0, 1, 1, 1, 0, -1]
  dy = [0, 1, 1, 1, 0, -1, -1, -1]
  x, y = 0, 0
  visited_nodes = set()
  visited_edges = set() # 같은 길 왕복하는 경우도 있을 수 있으므로 간선까지 고려
  visited_nodes.add((x, y))

  for d in arrows:
      for _ in range(2): # 대각선 교차 고려해서 0.5 길이씩 두 번
          nx = x + dx[d]
          ny = y + dy[d]
          # 새로운 경로로 노드 다시 방문한 경우
          if ((x, y), (nx, ny)) not in visited_edges:
              if (nx, ny) in visited_nodes:
                  answer += 1
          visited_nodes.add((nx, ny))
          # 무방향 간선
          visited_edges.add(((x, y), (nx, ny)))
          visited_edges.add(((nx, ny), (x, y)))
          x, y = nx, ny

  return answer</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드트리/Python] 메이즈 러너 (삼성 SW 역량테스트)]]></title>
            <link>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%ACPython-%EB%A9%94%EC%9D%B4%EC%A6%88-%EB%9F%AC%EB%84%88-%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%ACPython-%EB%A9%94%EC%9D%B4%EC%A6%88-%EB%9F%AC%EB%84%88-%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Fri, 11 Apr 2025 05:49:13 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.codetree.ai/ko/frequent-problems/problems/maze-runner">메이즈 러너</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>구현</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li>참가자 이동<ul>
<li><code>상하좌우</code> 순으로 이동했을 때 출구와의 맨해튼 거리가 <code>짧아질 때</code>에만 이동 수행</li>
</ul>
</li>
<li>출구와의 맨해튼 거리가 가장 짧은 참가자들 <code>후보</code>로 저장</li>
<li>각 참가자들 순회하며 <code>정사각형</code> 생성<ul>
<li><code>size</code>, <code>row</code>, <code>col</code> 순으로 <code>3</code>중 <code>for</code>문 돌면서 정사각형 생성(인덱스 조정 잘 하기)</li>
<li>참가자 <code>1명</code> 이상과 <code>출구</code>가 포함되는 즉시 정사각형 반환(사이즈 및 좌측상단과 우측하단의 좌표를)</li>
</ul>
</li>
<li>정사각형 <code>회전</code> 후 원래 배열에 적용<ul>
<li>참가자 위치와 출구 위치 또한 회전 후 적용</li>
</ul>
</li>
<li>이동한 사람들 개수를 정답에 추가</li>
<li>위 과정 k번 동안 반복 후 정답 출력</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">n, m, k = map(int, input().split())
maze = [list(map(int, input().split())) for _ in range(n)]
</code></pre>
</li>
</ul>
<h1 id="참가자-위치-정보-x-y-출구까지의-거리-인덱스">참가자 위치 정보: [x, y, 출구까지의 거리, 인덱스]</h1>
<p>people_pos = [[a - 1, b - 1, 100, idx] for idx, (a, b) in enumerate([tuple(map(int, input().split())) for _ in range(m)])]</p>
<h1 id="격자-내-참가자-배치-상태">격자 내 참가자 배치 상태</h1>
<p>people_arr = [[[] for _ in range(n)] for _ in range(n)]
for person in people_pos:
    x, y = person[0], person[1]
    people_arr[x][y].append(person[3])</p>
<h1 id="출구-위치-0-indexed">출구 위치 (0-indexed)</h1>
<p>ex, ey = map(lambda x: int(x) - 1, input().split())</p>
<p>def get_min_dist(sx, sy, ex, ey):
    &quot;&quot;&quot;맨해튼 거리 반환&quot;&quot;&quot;
    return abs(sx - ex) + abs(sy - ey)</p>
<p>def move(x, y, ex, ey):
    &quot;&quot;&quot;출구와 가까워지는 방향으로 1칸 이동&quot;&quot;&quot;
    for dx, dy in [(-1,0), (1,0), (0,-1), (0,1)]:  # 상하좌우
        nx, ny = x + dx, y + dy
        if 0 &lt;= nx &lt; n and 0 &lt;= ny &lt; n and maze[nx][ny] == 0:
            if get_min_dist(nx, ny, ex, ey) &lt; get_min_dist(x, y, ex, ey):
                return nx, ny, get_min_dist(nx, ny, ex, ey)
    return x, y, get_min_dist(x, y, ex, ey)</p>
<p>def make_rectangle(dist, sx, sy, ex, ey):
    &quot;&quot;&quot;출구와 참가자 1명 이상을 포함하는 가장 작은 정사각형 찾기&quot;&quot;&quot;
    dist += 1  # side = 거리 + 1
    for sz in range(2, dist + 1):  # 가능한 정사각형 크기
        for x1 in range(n - sz + 1):
            for y1 in range(n - sz + 1):
                x2, y2 = x1 + sz - 1, y1 + sz - 1
                if not (x1 &lt;= ex &lt;= x2 and y1 &lt;= ey &lt;= y2):
                    continue
                for tx, ty, *_ in people_pos:
                    if x1 &lt;= tx &lt;= x2 and y1 &lt;= ty &lt;= y2 and (tx != ex or ty != ey):
                        return sz, x1, y1, x2, y2
    return False</p>
<p>def rotate(side, sx, sy, endx, endy):
    &quot;&quot;&quot;정사각형 회전 + 출구 위치 업데이트 + 사람 위치 업데이트&quot;&quot;&quot;
    global ex, ey</p>
<pre><code># 회전 임시 배열
rotated_maze = [[0] * side for _ in range(side)]
rotated_people = [[[] for _ in range(side)] for _ in range(side)]

# 출구가 정사각형 내에 있을 경우 회전
if sx &lt;= ex &lt;= sx + side - 1 and sy &lt;= ey &lt;= sy + side - 1:
    lx, ly = ex - sx, ey - sy
    ex, ey = sx + ly, sy + side - 1 - lx

# 회전 처리
for i in range(side):
    for j in range(side):
        gi, gj = sx + i, sy + j
        ri, rj = j, side - 1 - i
        rotated_maze[ri][rj] = max(maze[gi][gj] - 1, 0) if maze[gi][gj] else 0
        rotated_people[ri][rj] = people_arr[gi][gj][:]

# 회전 결과 적용
for i in range(side):
    for j in range(side):
        gi, gj = sx + i, sy + j
        maze[gi][gj] = rotated_maze[i][j]
        people_arr[gi][gj] = rotated_people[i][j][:]

# 참가자 위치 정보 업데이트
for i in range(n):
    for j in range(n):
        for person in people_arr[i][j]:
            people_pos[person] = [i, j, get_min_dist(i, j, ex, ey), person]

return ex, ey</code></pre><h1 id="-시뮬레이션-시작-">=========================== 시뮬레이션 시작 ============================</h1>
<p>answer = 0
people_cnt = m</p>
<p>for _ in range(k):
    if people_cnt == 0:
        break</p>
<pre><code># 참가자 이동 처리
next_people_arr = [[[] for _ in range(n)] for _ in range(n)]
for idx, (x, y, _, _) in enumerate(people_pos):
    if x == -1:
        continue
    nx, ny, dist = move(x, y, ex, ey)
    people_pos[idx][:3] = [nx, ny, dist]
    next_people_arr[nx][ny].append(idx)
    if (nx, ny) != (x, y):  # 실제 이동 시 카운트 증가
        answer += 1
    if nx == ex and ny == ey:  # 출구 도착
        people_pos[idx] = [-1, -1, 100, idx]
        people_cnt -= 1
        next_people_arr[nx][ny].remove(idx)

people_arr = next_people_arr

if people_cnt == 0:
    break

# 출구와 가장 가까운 사람 기준으로 정사각형 선택
candidate_people = sorted([p for p in people_pos if p[0] != -1], key=lambda x: x[2])
min_dist = candidate_people[0][2]
rects = []

for person in candidate_people:
    if person[2] != min_dist:
        break
    rect = make_rectangle(person[2], person[0], person[1], ex, ey)
    if rect:
        rects.append(rect)

if rects:
    rects.sort()  # 좌상단 기준 우선
    ex, ey = rotate(*rects[0])  # 회전</code></pre><h1 id="-결과-출력-">=========================== 결과 출력 ============================</h1>
<p>print(answer)
print(ex + 1, ey + 1)  # 1-indexed 출력</p>
<p>```</p>
<p>시간: 54ms, 메모리: 16MB</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드트리/Python] 포탑 부수기 (삼성 SW 역량테스트)]]></title>
            <link>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%ACPython-%ED%8F%AC%ED%83%91-%EB%B6%80%EC%88%98%EA%B8%B0-%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%ACPython-%ED%8F%AC%ED%83%91-%EB%B6%80%EC%88%98%EA%B8%B0-%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Thu, 10 Apr 2025 09:09:31 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.codetree.ai/ko/frequent-problems/problems/destroy-the-turret">포탑 부수기</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>구현</li>
<li>bfs</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li>공격자 선정<ul>
<li>배열 내 최솟값</li>
<li>공격자가 될 수 있는 포탑들 후보 리스트<code>candidate</code>에 추가</li>
<li><code>candidate</code>를 행과 열의 합, 열 순으로 <code>오름차순</code> 정렬</li>
<li>공격 기록 뒤에서부터 돌며 만약 <code>candidate</code> 내에 있으면 공격자로 지정</li>
<li>없으면 공격자는 <code>candidate[0]</code></li>
<li>패널티 적용</li>
</ul>
</li>
<li>공격 대상자 선정<ul>
<li>위와 동일</li>
<li>조건 수정: 행과 열의 합, 열 순으로 <code>내림차순</code>, 공격 기록 <code>앞</code>에서부터</li>
<li>조건 추가: 공격자가 아님</li>
</ul>
</li>
<li>최단 경로 찾기<ul>
<li>무조건 <code>bfs</code>로!! (dfs로 하면 시간초과)</li>
<li>범위 벗어나면 반대쪽으로 넘어가게 <code>모듈러</code> 적용</li>
</ul>
</li>
<li>레이저 공격<ul>
<li>공격 관련 리스트에 추가</li>
<li>경로에 있는 포탑들은 공격자 공격력의 반만큼, 공격 대상자는 공격력만큼 피해</li>
<li>공격 받고 음수가 되면 <code>0</code>으로 치환</li>
</ul>
</li>
<li>포탑 공격<ul>
<li>공격 관련 리스트에 추가</li>
<li>공격 대상자는 공격력만큼 피해</li>
<li>주위 8칸에 있는 포탑들은 공격자 공격력의 반만큼 피해<ul>
<li>8칸 찾을 때에도 <code>모듈러</code> 적용</li>
<li>공격자가 아닌지 확인 필수</li>
</ul>
</li>
<li>공격 받고 음수가 되면 0으로 치환</li>
</ul>
</li>
<li>포탑 정비 및 공격 기록에 공격자 추가<ul>
<li>공격 관련 리스트에 없는 포탑들 <code>공격력+1</code></li>
<li>공격 기록에 공격자 추가</li>
</ul>
</li>
<li>위 과정 k만큼 반복 후, 배열 내 <code>최댓값</code> 출력</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">from collections import deque
</code></pre>
</li>
</ul>
<p>n, m, k = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(n)]
attacker_history = [] # 공격 기록 저장</p>
<h1 id="공격자-찾기">공격자 찾기</h1>
<p>def find_attacker():
    min_bomb = 5000
    tmp = []
    row, col = 0, 0
    for j in range(m):
        for i in range(n):
            if arr[i][j] != 0 and arr[i][j] &lt;= min_bomb:
                min_bomb = arr[i][j]
                row, col = i, j
                tmp.append((i, j))
    candidate = [bomb for bomb in tmp if arr[bomb[0]][bomb[1]] == min_bomb]
    candidate.sort(key=lambda x : (-(x[0]+x[1]), -x[1]))
    row, col = candidate[0]
    if len(candidate) &gt; 1:
        # 공격한지 가장 최근 포탑 선정
        for i in range(len(attacker_history) - 1, -1, -1):
            for j in range(len(candidate)):
                if attacker_history[i] == candidate[j]:
                    row, col = candidate[j]
                    break
            else:
                continue
            break
    arr[row][col] += n + m
    return row, col</p>
<h1 id="공격-대상자-찾기">공격 대상자 찾기</h1>
<p>def find_victim(ax, ay):
    max_bomb = 0
    tmp = []
    row, col = 0, 0
    for j in range(m - 1, -1, -1):
        for i in range(n - 1, -1, -1):
            if arr[i][j] != 0 and not (ax == i and ay == j) and arr[i][j] &gt;= max_bomb:
                max_bomb = arr[i][j]
                row, col = i, j
                tmp.append((i, j))
    candidate = [bomb for bomb in tmp if arr[bomb[0]][bomb[1]] == max_bomb]
    candidate.sort(key=lambda x : (x[0]+x[1], x[1]))</p>
<pre><code>if len(candidate) &gt; 1:
    row, col = candidate[0]
    # 일부만 공격기록 가지고 있을 때
    for candi in candidate:
        if candi not in attacker_history:
            return candi

    # 공격한지 가장 오래된 포탑 선정: 모두 공격 기록을 가지고 있을 때
    for i in range(len(attacker_history)):
        for j in range(len(candidate)):
            if attacker_history[i] == candidate[j]:
                row, col = candidate[j]
                break
        else:
            continue
        break

return row, col</code></pre><h1 id="우하좌상">우하좌상</h1>
<p>dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]</p>
<h1 id="최단-경로-찾기-dfs-금지시간초과">최단 경로 찾기: dfs 금지(시간초과)</h1>
<p>def find_route_bfs(x, y, ex, ey):
    visited = [[False] * m for _ in range(n)]
    queue = deque()
    queue.append((x, y, [(x, y)]))
    visited[x][y] = True</p>
<pre><code>while queue:
    cx, cy, path = queue.popleft()
    if cx == ex and cy == ey:
        return path
    for i in range(4):
        # 범위 벗어나면 반대쪽으로 가도록 모듈러 적용
        nx = (cx + dx[i]) % n
        ny = (cy + dy[i]) % m
        if not visited[nx][ny] and arr[nx][ny] &gt; 0:
            visited[nx][ny] = True
            queue.append((nx, ny, path + [(nx, ny)]))

return []</code></pre><p>for turn in range(k):
    # 남은 포탑이 1개면 중단
    if sum([(row.count(0)) for row in arr]) == n * m - 1:
        break</p>
<pre><code># 공격자, 공격대상자 지정
ax, ay = find_attacker()
vx, vy = find_victim(ax, ay)

# 공격 기록 추가
if (ax, ay) in attacker_history:
    attacker_history.remove((ax, ay))
attacker_history.append((ax, ay)) 

min_route = find_route_bfs(ax, ay, vx, vy)
attacked = [(ax, ay)] # 공격과 관련 있는 포탑들

# 레이저 공격
if len(min_route) &gt; 1:
    # 공격자인 첫 번째 원소 제거
    route = min_route[1:]
    for x, y in route:
        attacked.append((x, y))
        if x == vx and y == vy: # 공격 대상자 일때
            arr[x][y] -= arr[ax][ay]
            if arr[x][y] &lt; 0:
                arr[x][y] = 0
        else:
            arr[x][y] -= arr[ax][ay] // 2 # 그외: 절반 만큼 피해
            if arr[x][y] &lt; 0:
                arr[x][y] = 0

else: # 포탑 공격
    arr[vx][vy] -= arr[ax][ay]
    if arr[vx][vy] &lt; 0:
        arr[vx][vy] = 0
    attacked.append((vx, vy))
    # 시계 방향
    ddx = [-1, -1, 0, 1, 1, 1, 0, -1]
    ddy = [0, 1, 1, 1, 0, -1, -1, -1]
    for i in range(8):
        nx = (vx + ddx[i]) % n
        ny = (vy + ddy[i]) % m
        if arr[nx][ny] != 0 and not (nx == ax and ny == ay): # 공격자가 아니고, 포탑이 있을때
            arr[nx][ny] -= arr[ax][ay] // 2
            if arr[nx][ny] &lt; 0:
                arr[nx][ny] = 0
            attacked.append((nx, ny))

# 포탑 정비
for i in range(n):
    for j in range(m):
        if arr[i][j] != 0 and (i, j) not in attacked:
            arr[i][j] += 1</code></pre><h1 id="정답-출력-배열-내-최댓값">정답 출력: 배열 내 최댓값</h1>
<p>print(max([max(row) for row in arr]))</p>
<p>```</p>
<p>시간: 252ms, 메모리: 23MB</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드트리/Python] 왕실의 기사 대결 (삼성 SW 역량테스트)]]></title>
            <link>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%ACPython-%EC%99%95%EC%8B%A4%EC%9D%98-%EA%B8%B0%EC%82%AC-%EB%8C%80%EA%B2%B0-%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%ACPython-%EC%99%95%EC%8B%A4%EC%9D%98-%EA%B8%B0%EC%82%AC-%EB%8C%80%EA%B2%B0-%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Wed, 09 Apr 2025 16:43:05 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.codetree.ai/ko/frequent-problems/problems/royal-knight-duel">왕실의 기사 대결</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>구현</li>
<li>bfs</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li>명령 하나씩 수행하며 <code>밀릴 예정</code>인 기사들 반환<ul>
<li>현재 기사와 연결된 기사들 <code>큐</code>에 넣고 연쇄적으로 판단(<code>bfs</code>)</li>
<li>어느 과정 중에라도 벽을 만난다면 <code>빈</code> 값으로 반환</li>
</ul>
</li>
<li>밀릴 예정인 기사들의 <code>좌표 업데이트</code><ul>
<li>기사 배열에서 기존 자리 삭제 (<code>0</code>)</li>
<li>이동한 자리 인덱스로 채우기</li>
</ul>
</li>
<li>업데이트된 기사들 다시 한 번 순회하며 <code>데미지 계산</code><ul>
<li>각 기사들의 자리에 있는 함정 개수 카운트 = 데미지 배열에 업데이트</li>
<li>동시에 함정 개수 만큼 <code>체력 감소</code></li>
</ul>
</li>
<li>체력이 0인 기사가 있다면 기사 배열에서 <code>제거</code>(<code>0</code>)</li>
<li>데미지 배열 순회하며 <code>음수가 아닌</code> 경우에만 <code>정답</code>에 추가</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">from collections import deque
</code></pre>
</li>
</ul>
<p>l, n, q = map(int, input().split())
fall_info = [list(map(int, input().split())) for _ in range(l)] # 벽, 함정 배열
arr = [[0] * l for _ in range(l)] # 기사 배열
people_pos = [[] for _ in range(n + 1)] # 각 기사 좌표
people_power = [0] # 각 기사 체력</p>
<h1 id="기사-배열에-기사-표시">기사 배열에 기사 표시</h1>
<p>for idx in range(1, n + 1):
    r, c, h, w, k = map(int, input().split())
    for i in range(r - 1, r - 1 + h):
        for j in range(c - 1, c - 1 + w):
            arr[i][j] = idx
            people_pos[idx].append([i, j])
    people_power.append(k)</p>
<p>commands = [list(map(int, input().split())) for _ in range(q)] # 명령</p>
<h1 id="상우하좌">상우하좌</h1>
<p>dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]</p>
<h1 id="체스판-내에-있는지-확인">체스판 내에 있는지 확인</h1>
<p>def in_range(x, y):
    return 0 &lt;= x &lt; l and 0 &lt;= y &lt; l</p>
<h1 id="밀릴-예정인-기사들-반환-함수">밀릴 예정인 기사들 반환 함수</h1>
<p>def get_candidate(idx, direction):
    candidate = set() # 일직선상에 있는 밀릴 기사들 후보
    candidate.add(idx) # 시작 기사는 무조건 추가</p>
<pre><code>q = deque([idx])
# 현재 기사와 연결된 기사 모두 큐에 추가 (상하좌우에 따라 조건 다름)
while q:
    knight = q.popleft() # 현재 기사
    rows = set() # 시작 기사의 모든 행
    cols = set() # 시작 기사의 모든 열
    for x, y in people_pos[knight]:
        rows.add(x)
        cols.add(y)
    rows = list(rows)
    rows.sort()
    cols = list(cols)
    cols.sort()

    if direction == 0: # 상
        for col in cols:
            if not in_range(rows[0] - 1, col) or fall_info[rows[0] - 1][col] == 2: # 벽 만나면 모두 이동 불가
                return {}
            if in_range(rows[0] - 1, col) and arr[rows[0] - 1][col] &gt; 0: # 기사가 맞닿아 있을 때
                candidate.add(arr[rows[0] - 1][col])
                q.append(arr[rows[0] - 1][col])
    elif direction == 1: # 우
        for row in rows:
            if not in_range(row, cols[-1] + 1) or fall_info[row][cols[-1] + 1] == 2: # 벽 만나면 모두 이동 불가
                return {}
            if in_range(row, cols[-1] + 1) and arr[row][cols[-1] + 1] &gt; 0: # 기사가 맞닿아 있을 때
                candidate.add(arr[row][cols[-1] + 1])
                q.append(arr[row][cols[-1] + 1])
    elif direction == 2: # 하
        for col in cols:
            if not in_range(rows[-1] + 1, col) or fall_info[rows[-1] + 1][col] == 2: # 벽 만나면 모두 이동 불가
                return {}
            if in_range(rows[-1] + 1, col) and arr[rows[-1] + 1][col] &gt; 0: # 기사가 맞닿아 있을 때
                candidate.add(arr[rows[-1] + 1][col])
                q.append(arr[rows[-1] + 1][col])
    elif direction == 3: # 좌
        for row in rows:
            if not in_range(row, cols[0] - 1) or fall_info[row][cols[0] - 1] == 2: # 벽 만나면 모두 이동 불가
                return {}
            if in_range(row, cols[0] - 1) and arr[row][cols[0] - 1] &gt; 0: # 기사가 맞닿아 있을 때
                candidate.add(arr[row][cols[0] - 1])
                q.append(arr[row][cols[0] - 1])

return candidate</code></pre><p>people_damaged = [0] * len(people_pos) # 각 기사가 받은 데미지</p>
<p>for idx, d in commands:
    # 사라진 기사일 경우 제외
    if people_power[idx] == -1:
        continue</p>
<pre><code>candidates = get_candidate(idx, d)

# 밀린 좌표 업데이트 및 기존 자리 삭제
for candi in candidates:
    updated_pos = []
    for x, y in people_pos[candi]:
        arr[x][y] = 0
        updated_pos.append([x + dx[d], y + dy[d]])
    people_pos[candi] = [row[:] for row in updated_pos]

# 밀린 좌표로 자리 표시
for candi in candidates:
    remain = people_power[candi] # 체력
    for x, y in people_pos[candi]:
        arr[x][y] = candi
        # 데미지 받을 때
        if fall_info[x][y] == 1: # 함정
            if candi != idx: # 명령 받은 기사 제외
                people_damaged[candi] += 1 # 데미지 추가
                people_power[candi] -= 1 # 체력 감소

# 체력 음수인 기사 제거
for candi in candidates:
    if people_power[candi] &lt;= 0:
        for x, y in people_pos[candi]:
            arr[x][y] = 0
            people_pos[candi] = [-1, -1]
            people_power[candi] = -1
            people_damaged[candi] = -1</code></pre><h1 id="사라진-기사들-제외-데미지-총합-출력">사라진 기사들 제외 데미지 총합 출력</h1>
<p>answer = 0
for damage in people_damaged:
    if damage != -1:
        answer += damage
print(answer)</p>
<p>```</p>
<p>시간: 67ms, 메모리: 18MB</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드트리/Python] 고대 문명 유적 탐사 (삼성 SW 역량테스트)]]></title>
            <link>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%ACPython-%EA%B3%A0%EB%8C%80-%EB%AC%B8%EB%AA%85-%EC%9C%A0%EC%A0%81-%ED%83%90%EC%82%AC-%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%ACPython-%EA%B3%A0%EB%8C%80-%EB%AC%B8%EB%AA%85-%EC%9C%A0%EC%A0%81-%ED%83%90%EC%82%AC-%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Mon, 07 Apr 2025 12:47:20 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.codetree.ai/ko/frequent-problems/problems/ancient-ruin-exploration">고대 문명 유적 탐사</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>구현</li>
<li>dfs</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li><p>탐색 진행
 1)<code>3X3</code> 슬라이싱 후 <code>90</code>, <code>180</code>, <code>270</code>으로 회전</p>
<ul>
<li><p>총 <code>27</code>개의 경우의 수 발생</p>
<p>2) 각 경우에서 유물가치가 <code>최대</code>가 되는 배열 구하기</p>
</li>
<li><p>연결된 조각의 개수(<code>dfs</code> 또는 <code>bfs</code>로) 구해서 모두 더하기</p>
</li>
<li><p>이때 사라진 조각들의 좌표 모두 저장하기 <code>total_route</code></p>
</li>
</ul>
</li>
<li><p>유물 1차 획득
 1) 사라진 조각들 자리 <code>total_route</code> 에 벽의 숫자 채우기
 2) 벽의 숫자를 가리키는 인덱스는 <code>전 과정</code>에서 계속 <code>보유</code>하고 있어야함</p>
</li>
<li><p>유물 연쇄 획득</p>
<ul>
<li>2번 과정과 동일, 더 이상 없을 때까지 <code>반복</code></li>
</ul>
</li>
<li><p>각 턴 별 <code>정답</code> 출력</p>
</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">k, m = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(5)]
nums = list(map(int, input().split()))
# 북 남 동 서
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]
# 행렬 회전 함수
def rotate(grid, degree):
  result = [[0] * len(grid[0]) for _ in range(len(grid))]
  for i in range(3):
      for j in range(3):
          if degree == 1: # 90도
              result[j][3 - 1 - i] = grid[i][j]
          elif degree == 2: # 180도
              result[3 - 1 - i][3 - 1 - j] = grid[i][j]
          elif degree == 3: # 270도
              result[3 - 1 - j][i] = grid[i][j]
  return result
</code></pre>
</li>
</ul>
<h1 id="연결-요소-개수-세기">연결 요소 개수 세기</h1>
<p>def dfs(grid, x, y, visited, path):
    visited[x][y] = True
    path.add((x, y))
    cnt = 1
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if 0 &lt;= nx &lt; 5 and 0 &lt;= ny &lt; 5:
            if grid[nx][ny] == grid[x][y] and not visited[nx][ny]:
                cnt += dfs(grid, nx, ny, visited, path)
    return cnt</p>
<h1 id="유물-가치-계산">유물 가치 계산</h1>
<p>def get_max_val(grid):
    max_val = 0
    visited = [[False] * 5 for _ in range(5)]
    total_route = [] # 모든 사라진 조각의 위치 저장
    for i in range(5):
        for j in range(5):
            if not visited[i][j]:
                # 유물 삭제를 위해 기록 저장
                path = set()
                val = dfs(grid, i, j, visited, path)
                if val &gt;= 3: # 유물 완성
                    max_val += val
                    total_route.extend(path)
                    # 유물 삭제
                    for x, y in path:
                        grid[x][y] = -1
    return max_val, total_route</p>
<h1 id="유물-사라진-곳-숫자-채우기">유물 사라진 곳 숫자 채우기</h1>
<p>def fill(grid, route, idx):
    route.sort(key=lambda x: (x[1], -x[0])) # 작은 열, 큰 행 순으로 정렬
    for i, j in route:
        grid[i][j] = nums[idx]
        idx += 1
    return idx # 마지막 조각까지 채우고 그 다음 벽면 숫자의 인덱스 반환</p>
<p>flag = True # 탐사 진행 가능 여부
wall_idx = 0 # 현재 가리키고 있는 벽면 숫자의 인덱스
turn = 0
while turn &lt; k and flag:
    flag = True
    answer = 0 # 각 턴마다의 유물 가치</p>
<pre><code># ==== 탐사 진행 시작 ====
# 중심점 지정
candidate = [] # 유물 가치 최대가 되는 배열 후보(유물가치, 배열, 회전각도, 회전중심열, 회전중심행)
max_value = 0 # 최대 유물 가치
for r in range(0, 3):
    for c in range(0, 3):
        # 배열 슬라이싱
        tmp = []
        for i in range(r, r + 3):
            row = []
            for j in range(c, c + 3):
                row.append(arr[i][j])
            tmp.append(row)

        # 3방향 회전
        rotated_tmp = []
        for degree in range(1, 4):
            rotated_tmp = rotate(tmp, degree)
            # 원래 배열에 합치기, 복사본으로
            copy_arr = [row[:] for row in arr]
            for rr in range(r, r + 3):
                for cc in range(c, c + 3):
                    copy_arr[rr][cc] = rotated_tmp[rr - r][cc - c]
            get_max_value, total_route = get_max_val(copy_arr)
            if get_max_value &gt;= max_value:
                candidate.append([get_max_value, copy_arr, degree, c, r, total_route])


candidate.sort(key=lambda x: (-x[0], x[2], x[3], x[4]))
# 유물가치가 3개 이상 되는 경우가 없을 경우 탐사 중단
if candidate[0][0] &lt; 3:
    flag = False
    break
selected_arr = candidate[0][1] # 유물가치가 최대가 되도록 회전한 배열
# ==== 탐사 진행 끝 ====

# ==== 유물 1차 획득 시작 ====
answer += candidate[0][0] # 사라진 조각 개수
total_route = candidate[0][5] # 사라진 조각들의 좌표

wall_idx = fill(selected_arr, total_route, wall_idx) # 다 채우고 다음 진행을 위해 벽면 인덱스 갱신
# ==== 유물 1차 획득 끝====

# ==== 유물 연쇄 획득 시작====
flag2 = True
while flag2:
    max_value, total_route = get_max_val(selected_arr)
    if max_value &lt; 3:
        flag2 = False
        break
    answer += max_value

    wall_idx = fill(selected_arr, total_route, wall_idx) # 다 채우고 다음 진행을 위해 벽면 인덱스 갱신
# ==== 유물 연쇄 획득 끝====

# 정답 출력
print(answer, end=&quot; &quot;)

# 다음 진행을 위해 arr 갱신
arr = [row[:] for row in selected_arr]
turn += 1</code></pre><p>```</p>
<p>시간: 144ms, 메모리: 21MB</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드트리/Python] 미지의 공간 탈출 (삼성 SW 역량테스트)]]></title>
            <link>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%AC%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%AF%B8%EC%A7%80%EC%9D%98-%EA%B3%B5%EA%B0%84-%ED%83%88%EC%B6%9C-Python</link>
            <guid>https://velog.io/@yunni_/%EC%BD%94%EB%93%9C%ED%8A%B8%EB%A6%AC%EC%82%BC%EC%84%B1-SW-%EC%97%AD%EB%9F%89%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%AF%B8%EC%A7%80%EC%9D%98-%EA%B3%B5%EA%B0%84-%ED%83%88%EC%B6%9C-Python</guid>
            <pubDate>Sat, 05 Apr 2025 17:54:05 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.codetree.ai/ko/frequent-problems/problems/escape-unknown-space">미지의 공간 탈출</a></p>
<h4 id="🔍-알고리즘-분류">🔍 알고리즘 분류</h4>
<ul>
<li>구현</li>
<li>bfs</li>
</ul>
<h4 id="💡-문제-풀이">💡 문제 풀이</h4>
<ol>
<li>시간의 벽 <code>전개</code>하기</li>
<li>시간의 벽에서 <code>면 간의 이동</code> 구현하기 (인덱스 조정이 까다로움..)</li>
<li>시간의 벽에서 <code>bfs</code> 수행<ul>
<li><code>이상현상 이동</code>도 동시 수행<ul>
<li>지나온 turn을 set으로 관리하여 turn마다 <code>단 한번</code>만 실행되도록 해야 함</li>
</ul>
</li>
</ul>
</li>
<li>바닥면에서 시간의 벽과의 <code>통로</code> 찾기</li>
<li>위 지점을 시작점으로 <code>bfs</code> 수행<ul>
<li>예외처리: 통로가 탈출구일 때</li>
<li><code>이상현상 이동</code>도 동시 수행</li>
</ul>
</li>
<li>정답(<code>탈출구</code> 지점에서의 시간) 출력<ul>
<li>예외처리: 시간의 벽과 바닥면이 이동할 수 있는 통로가 <code>없을 때</code> (이상현상 이동으로 인해)</li>
</ul>
</li>
</ol>
<h4 id="📄-코드">📄 코드</h4>
<ul>
<li>Python<pre><code class="language-python">from collections import deque, defaultdict
</code></pre>
</li>
</ul>
<p>n, m, f = map(int, input().split())
floor_map = [] # 바닥면(2차원)
top_left = () # 시간의 벽 윗면 시작점 위치
current = () # 타임머신 초기 위치</p>
<h1 id="바닥면-저장">바닥면 저장</h1>
<p>for i in range(n):
    row = list(map(int, input().split()))
    floor_map.append(row)
    for j in range(len(row)):
        # 바닥에서 시간의 벽이 시작하는 위치 저장
        if len(top_left) == 0 and row[j] == 3:
            top_left = (i, j)</p>
<p>time_map = [] # 시간의 벽(3차원)
side = [] # 동 서 남 북 위</p>
<p>for i in range(1, 5 * m + 1):
    side.append(list(map(int, input().split())))
    # 한 면 완성되면 시간의벽 에 저장
    if i % m == 0:
        time_map.append(side)
        side = []</p>
<p>anomaly = defaultdict(list) # 이상현상 해시맵
for _ in range(f):
    r, c, d, v = map(int, input().split())
    # v를 key, 나머지를 value로 갖도록 해시맵에 저장
    anomaly[v].append([r, c, d]) # v에 대해 여러 이상현상이 있을 수 있으므로 list 사용</p>
<h1 id="시간의-벽-전개">시간의 벽 전개</h1>
<p>flat_map = [[-1] * 3 * m for _ in range(3 * m)]</p>
<h1 id="동--왼쪽으로-90도-회전">동 = 왼쪽으로 90도 회전</h1>
<p>tmp = [[0] * m for _ in range(m)]
for i in range(m):
    for j in range(m):
        tmp[m - j - 1][i] = time_map[0][i][j]
for i in range(m, 2 * m):
    for j in range(2 * m, 3 * m):
        flat_map[i][j] = tmp[i - m][j - 2 * m]</p>
<h1 id="서--오른쪽으로-90도-회전">서 = 오른쪽으로 90도 회전</h1>
<p>tmp = [[0] * m for _ in range(m)]
for i in range(m):
    for j in range(m):
        tmp[j][m - 1 - i] = time_map[1][i][j]
for i in range(m, 2 * m):
    for j in range(0, m):
        flat_map[i][j] = tmp[i - m][j]</p>
<h1 id="남--그대로">남 = 그대로</h1>
<p>for i in range(2 * m, 3 * m):
    for j in range(m, 2 * m):
        flat_map[i][j] = time_map[2][i - 2 * m][j - m]</p>
<h1 id="북--180도-회전">북 = 180도 회전</h1>
<p>tmp = [[0] * m for _ in range(m)]
for i in range(m):
    for j in range(m):
        tmp[m - 1 - i][m - 1 - j] = time_map[3][i][j]
for i in range(0, m):
    for j in range(m, 2 * m):
        flat_map[i][j] = tmp[i][j - m]     </p>
<h1 id="위">위</h1>
<p>for i in range(m, 2 * m):
    for j in range(m, 2 * m):
        flat_map[i][j] = time_map[4][i - m][j - m]
        if flat_map[i][j] == 2: # 타임머신 초기 위치 저장
            current = (i, j)</p>
<h1 id="동서남북-중-어느-면에-있는지-확인하는-함수">동서남북 중 어느 면에 있는지 확인하는 함수</h1>
<p>def check_side(x, y):
    if m &lt;= x &lt; 2 * m and 2 * m &lt;= y &lt; 3 * m: # 동
        return 0
    elif m &lt;= x &lt; 2 * m and 0 &lt;= y &lt; m: # 서
        return 1
    elif 2 * m &lt;= x &lt; 3 * m and m &lt;= y &lt; 2 * m: # 남
        return 2
    elif 0 &lt;= x &lt; m and m &lt;= y &lt; 2 * m: # 북
        return 3</p>
<h1 id="동-서-남-북">동 서 남 북</h1>
<p>dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]</p>
<h1 id="이상현상-이동한-turn-기록">이상현상 이동한 turn 기록</h1>
<p>visited_turn = set()</p>
<h1 id="옆면-이동-함수">옆면 이동 함수</h1>
<p>def move_side(x, y):
    nx, ny = -1, -1
    if check_side(x, y) == 0: # 동
        if x == m: # 동 -&gt; 북
            nx = (3 * m - y - 1)
            ny = 2 * m - 1
        elif x == 2 * m - 1: # 동 -&gt; 남
            nx = 3 * m - 1 - (3 * m - y - 1)
            ny = 2 * m - 1
    elif check_side(x, y) == 1: # 서
        if x == m: # 서 -&gt; 북
            nx = y
            ny = m
        elif x == 2 * m - 1: # 서 -&gt; 남
            nx = (3 * m - y - 1)
            ny = m
    elif check_side(x, y) == 2: # 남
        if y == 2 * m - 1: # 남 -&gt; 동
            nx = 2 * m - 1
            ny = 3 * m - 1 - (3 * m - x - 1)
        elif y == m: # 남 -&gt; 서
            nx = 2 * m - 1
            ny = (3 * m - x - 1)
    elif check_side(x, y) == 3: # 북
        if y == 2 * m - 1: # 북 -&gt; 동
            nx = m
            ny = 3 * m - x - 1
        elif y == m: # 북 -&gt; 서
            nx = m
            ny = x</p>
<pre><code>return (nx, ny)</code></pre><h1 id="시간의-벽에서의-bfs">시간의 벽에서의 bfs</h1>
<p>def bfs(x, y):
    time[x][y] = 0
    q = deque([(x, y)])
    while q:
        x, y = q.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 &lt;= nx &lt; 3 * m and 0 &lt;= ny &lt; 3 * m:
                # 이상현상 이동
                turn = time[x][y] + 1
                for v in anomaly:
                    if (turn % v == 0):
                        # 이상현상 이동이 해당 turn에 단 한 번만 이동하도록
                        if turn not in visited_turn:
                            visited_turn.add(turn)
                            for idx, val in enumerate(anomaly[v]):
                                r, c, d = val
                                floor_map[r][c] = 1
                                nr = r + dx[d]
                                nc = c + dy[d]
                                # 벽이 아니면 이상현상 이동
                                if 0 &lt;= nr &lt; n and 0 &lt;= nc &lt; n and floor_map[nr][nc] == 0:
                                    floor_map[nr][nc] = 1
                                    anomaly[v][idx] = [nr, nc, d] # 이상현상 위치 갱신</p>
<pre><code>            # 나아갈 수 있는 경우 시간 기록
            if time[nx][ny] &gt; time[x][y] + 1: # 최단 시간 보장
                # 면 안에서의 이동
                if flat_map[nx][ny] == 0:
                    time[nx][ny] = time[x][y] + 1
                    q.append((nx, ny))
                # 면을 넘어갈 때
                elif flat_map[nx][ny] == -1: # 옆면 이동
                    nx, ny = move_side(x, y)

                    if flat_map[nx][ny] == 0:
                        if time[nx][ny] &gt; time[x][y] + 1:
                            time[nx][ny] = time[x][y] + 1
                            q.append((nx, ny))</code></pre><h1 id="시간의-벽-내-시간-기록">시간의 벽 내 시간 기록</h1>
<p>time = [[int(1e9)] * 3 * m for _ in range(3 * m)] 
bfs(current[0], current[1])</p>
<h1 id="바닥면-내-시간-기록">바닥면 내 시간 기록</h1>
<p>time_floor = [[int(1e9)] * n for _ in range(n)]</p>
<h1 id="시간의-벽에서-바닥으로-이동할-수-있는-통로-찾기">시간의 벽에서 바닥으로 이동할 수 있는 통로 찾기</h1>
<p>path = ()
ith = -1
jth = -1
for i in range(top_left[0] - 1, top_left[0] + m + 1):
    ith += 1
    for j in range(top_left[1] - 1, top_left[1] + m + 1):
        jth += 1
        if floor_map[i][j] == 0:
            path = (i, j)
            if j == top_left[1] + m: # 동
                time_floor[i][j] = time[m + ith - 1][3 * m - 1] + 1
            elif j == top_left[1] - 1: # 서
                time_floor[i][j] = time[m + ith - 1][0] + 1
            elif i == top_left[0] + m: # 남
                time_floor[i][j] = time[3 * m - 1][m + jth - 1] + 1
            elif i == top_left[0] - 1: # 북
                time_floor[i][j] = time[0][m + jth - 1] + 1
    jth = -1</p>
<p>ans = -1</p>
<h1 id="바닥면에서의-bfs">바닥면에서의 bfs</h1>
<p>def bfs2(x, y):
    global ans
    # 엣지케이스: 탈출구가 연결 통로인 경우
    if floor_map[x][y] == 4:
        ans = time_floor[x][y]
        return
    q = deque([(x, y)])
    while q:
        x, y = q.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 &lt;= nx &lt; n and 0 &lt;= ny &lt; n:
                # 탈출구 도착
                if floor_map[nx][ny] == 4:
                    time_floor[nx][ny] = time_floor[x][y] + 1
                    ans = time_floor[nx][ny]
                    return
                # 이상현상 이동
                turn = time_floor[x][y] + 1
                for v in anomaly:
                    if (turn % v == 0):
                        if turn not in visited_turn:
                            visited_turn.add(turn)
                            for idx, val in enumerate(anomaly[v]):
                                r, c, d = val
                                floor_map[r][c] = 1
                                nr = r + dx[d]
                                nc = c + dy[d]
                                if 0 &lt;= nr &lt; n and 0 &lt;= nc &lt; n and floor_map[nr][nc] == 0:
                                    floor_map[nr][nc] = 1
                                    anomaly[v][idx] = [nr, nc, d]<br>                # 나아갈 수 있는 경우 시간 기록
                if floor_map[nx][ny] == 0 and time_floor[nx][ny] &gt; time_floor[x][y] + 1: # 최단 시간 보장
                    time_floor[nx][ny] = time_floor[x][y] + 1
                    q.append((nx, ny))</p>
<h1 id="이상현상-이동으로-바닥으로-이동할-수-없는-경우-제외">이상현상 이동으로 바닥으로 이동할 수 없는 경우 제외</h1>
<p>if len(path):
    bfs2(path[0], path[1])</p>
<h1 id="정답-출력">정답 출력</h1>
<p>print(ans)</p>
<p>```</p>
<p>시간: 51ms, 메모리: 17MB</p>
]]></description>
        </item>
    </channel>
</rss>