<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>성준이의 개발블로그</title>
    <link>https://dev-sungjun.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 26 Jun 2026 08:37:20 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>기린성준</managingEditor>
    <item>
      <title>[Python] 백준 3190번 문제 풀이 - 뱀</title>
      <link>https://dev-sungjun.tistory.com/92</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/3190&quot;&gt;https://www.acmicpc.net/problem/3190&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 뱀이 벽에 부딪히거나 자기 자신과 부딪혀서 게임이 끝날 때의 이동 시간을 출력하는 문제입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;뱀은 처음 0,0에서 시작하고 오른쪽 방향을 바라보고 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;뱀은 매초마다 이동하는데, 몸 길이를 &lt;b&gt;바라보는 방향으로 늘려 머리를 이동&lt;/b&gt;시킵니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이동하는 칸에 사과가 있다면 사과가 없어지고 몸 길이가 1길어지고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이동하는 칸에 사과가 없다면 꼬리 부분이 잘려 몸 길이가 그대로인 채로 이동하는 것과 같습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;방향은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;시간 방향&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;형식으로 주어지는데 특정 시간이 지났을 때 특정 방향(오른쪽 or 왼쪽)으로 회전합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;방향이 &amp;ldquo;D&amp;rdquo;라면 오른쪽으로 회전합니다. 만약 오른쪽이였다면 아래를 바라보게 되고,&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;방향이 &amp;ldquo;L&amp;rdquo;이라면 왼쪽으로 회전합니다. 만약 오른쪽이였다면 위를 바라보게 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 저는 칸을 다음과 같이 나누었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그냥 칸 : 0&lt;/li&gt;
&lt;li&gt;사과가 있는 칸 : 1&lt;/li&gt;
&lt;li&gt;뱀이 있는 칸 : 2 &amp;rarr; 원래 Snake의 &amp;ldquo;S&amp;rdquo;로 하려했으나 숫자 배열이기 때문에 비슷한 모양인 2로 했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 while무한루프로 시간이 계속 경과되게 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 특정 시간에 뱀이 회전하므로 먼저 특정 시간이 된다면 그 시간에 맞게 방향을 회전합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;회전 하는 것은 좌하상우 이동배열을 만들어두고 1을 더하고 %4 하는 것과 1을 빼고 %4 하는 것으로 구분했습니다. &lt;b&gt;&amp;rarr;&lt;/b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; (k&amp;plusmn;1)%4&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 바라보는 방향으로 이동할 칸을 탐색합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;만약에 다음 칸이&lt;b&gt; 밖으로 벗어나거나 자기자신(=2)면 while문을 종료&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음 칸에 사과가 있고 없고에서 꼬리를 없앨지 말지가 결정이 되는데요&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;꼬리를 없애는 것은 큐를 사용해서 했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;큐에 맨 처음 들어갔던 게 꼬리가 되고 마지막에 들어갔던건 머리가 되게 한다음에&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사과가 없다면 큐의 맨처음 원소를 없애는 방식으로 꼬리가 없어지는 것을 구현했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 dfs로 탐색하려다가 2번 예제에서 꼬리가 제대로 없어지지 않을 것이라는 것을 알고 큐로 했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이동했으면 시간을 1초 늘립니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;이 아이디어를 정리하면 다음과 같습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;시간 경과하는 while문을 돌린다.&lt;/li&gt;
&lt;li&gt;현재 시간이 방향을 바꾸는 시간이라면 뱀이 바라보는 방향을 바꾼다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;오른쪽인지 왼쪽인지 따라서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(k&amp;plusmn;1)%4&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;다음칸을 확인하고 밖으로 나가거나 자기자신이 나온다면 시간을 1초 늘리고 while문을 탈출한다.&lt;/li&gt;
&lt;li&gt;머리를 이동시킨다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;만약 사과가 있다면 머리를 이동시킨 이후에 꼬리를 자르지 않는다.&lt;/li&gt;
&lt;li&gt;사과가 없다면 머리를 이동시킨 이후에 꼬리를 자른다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;머리 위치를 최신화하고 시간을 1 증가시킨다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반복문 내부 연산들의 시간복잡도를 써보면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방향 변경 : O(1)&lt;/li&gt;
&lt;li&gt;다음칸 확인 : O(1)&lt;/li&gt;
&lt;li&gt;사과 있는지 없는지 확인 후 머리 이동 후 꼬리 자르기 : O(1)&lt;/li&gt;
&lt;li&gt;머리 위치 확인 후 시간 증가시키기 : O(1)&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사과가 하나도 없어서 뱀의 길이가 1인채로 계속 무한루프를 돌 수도 있지만 &lt;b&gt;10000초가 지난 이후에는 방향 전환이 일어나지 않기 때문에&lt;/b&gt; 최대 10000 X O(1)하고 마지막에 그래프를 탐색하는 것은 많이 이동해봤자 끝까지 이동하는 NXN 맵이기 때문에 &lt;b&gt;최대 N만큼 이동&lt;/b&gt;하게 됩니다. 그러면 100정도 이동하고 총 10100 정도의 시간이 걸리기 때문에 10100 X O(1)이기 때문에 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 아이디어를 코드로 구현하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;from collections import deque

n = int(input())
k = int(input())

graph = [[0] * n for _ in range(n)]

for _ in range(k):
    y, x = map(int, input().split())
    graph[y-1][x-1] = 1

directions = {}
l = int(input())
for _ in range(l):
    sec, direction = input().split()
    directions[int(sec)] = direction

k = 0
dy = [0, 1, 0, -1]
dx = [1, 0, -1, 0]
queue = deque()

time = 0
y = 0
x = 0
queue.append((y,x))

while True:
    # 방향 결정
    if time in directions:
        if directions[time] == &quot;D&quot;:
            k = (k + 1) % 4
        else:
            k = (k-1) % 4

    # 다음 칸
    ny = y + dy[k]
    nx = x + dx[k]
    # 다음 칸이 벗어나거나 2일 경우
    if not ((0&amp;lt;=ny&amp;lt;n) and (0&amp;lt;=nx&amp;lt;n)) or graph[ny][nx] == 2:
        time += 1
        break

    queue.append((ny, nx))
    if graph[ny][nx] == 1:
        graph[ny][nx] = 2  # 머리 이동
    # 사과가 없는 경우
    elif graph[ny][nx] == 0:
        graph[ny][nx] = 2  # 머리 이동
        # 꼬리 제거
        qy, qx = queue.popleft()
        graph[qy][qx] = 0

    # 머리 위치 최신화
    y = ny
    x = nx
    # 횟수 늘리기
    time += 1

print(time)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>구현</category>
      <category>백준 3190 파이썬</category>
      <category>백준 뱀 파이썬</category>
      <category>큐</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/92</guid>
      <comments>https://dev-sungjun.tistory.com/92#entry92comment</comments>
      <pubDate>Wed, 10 Sep 2025 20:39:55 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 11866번 문제 풀이 - 요세푸스 문제 0</title>
      <link>https://dev-sungjun.tistory.com/91</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11866&quot;&gt;https://www.acmicpc.net/problem/11866&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 요새푸스 순열을 출력하면 되는 문제입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;만약에 (7,3) 요시푸스 순열이라면 &amp;lt;3,6,2,7,5,1,4&amp;gt;가 나오게 되는데요 어떤 과정을 거쳐서 나오게 되는거냐면&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현재 인덱스에서 k-1을 더하고 전체 개수로 나머지 연산하여 인덱스를 구하고 그 수를 빼는 과정입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;idx = (idx +k-1) % length&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;라는 공식이 나옵니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;인덱스는 0으로 시작합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 K는 3이니 K-1 = 2므로 각 연산마다 2를 더해줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(1,2,3,4,5,6,7) -&amp;gt; 3
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(0 + k-1)%7 해서 인덱스 2가 나오게 되고 인덱스 2번은 3이므로 3을 뺍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(1,2,4,5,6,7) -&amp;gt; 6
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(2 + 3 - 1) % 6 &amp;rarr; 4가 나오게 되고 인덱스 4는 6이므로 6을 뺍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(1,2,4,5,7) -&amp;gt; 2
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(4 + 3 -1) % 5 &amp;rarr; 1 이 나오게 되고 인덱스 1은 2이므로 2를 뺍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(1,4,5,7) -&amp;gt; 7
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(1+3-1) % 4 &amp;rarr; 3이 나오게 되고 인덱스 3은 7이므로 7을 뺍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(1,4,5) -&amp;gt; 5&lt;/li&gt;
&lt;li&gt;(1,4) -&amp;gt; 1&lt;/li&gt;
&lt;li&gt;(4) -&amp;gt; 4&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;나머지 3개의 연산도 다음 형식으로 진행되게 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 있던 공식을 사용해서 요세푸스 순열을 만들고 출력하면 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아이디어를 정리하면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;인덱스를 idx = (idx + k -1) % length로 해서 최신화 합니다.&lt;/li&gt;
&lt;li&gt;배열에서 인덱스를 빼고 결과 배열에 저장합니다.&lt;/li&gt;
&lt;li&gt;출력 형식에 맞춰서 출력합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 길이만큼 반복하니 O(N)이 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;N은 1000이니 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 아이디어를 처음에는 다음과 같이 remove를 사용해서 구현했었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;n, k = map(int, input().split())

num_list = []
result = []
for i in range(1, n+1):
    num_list.append(i)

idx = 0
for _ in range(n):
    idx = (idx + k-1) % len(num_list)
    num = num_list[idx]
    num_list.remove(num)
    result.append(num)

print(&quot;&amp;lt;&quot;, end=&quot;&quot;)
print(&quot;, &quot;.join(map(str, result)), end=&quot;&quot;)
print(&quot;&amp;gt;&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;그러다가 pop을 사용해서 인덱스로 빼는 방법이 있다는 것을 알았고 그것을 사용하였고 길이 계산을 한번만 하는 코드로 수정하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1757493110808&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, k = map(int, input().split())

num_list = []
result = []
for i in range(1, n+1):
    num_list.append(i)

idx = 0
length = len(num_list)
for _ in range(n):
    idx = (idx + k-1) % length
    result.append(num_list.pop(idx))
    length -= 1

print(&quot;&amp;lt;&quot;, end=&quot;&quot;)
print(&quot;, &quot;.join(map(str, result)), end=&quot;&quot;)
print(&quot;&amp;gt;&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;배운 점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 관련 메서드에 대해 학습하였습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;remove(item)를 사용하면 배열에서 특정 값을 제거할 수 있고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;pop(idx)을 사용하면 배열에서 특정 인덱스를 제거할 수 있다는 것을 알았습니다.&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>백준 11866 파이썬</category>
      <category>백준 요세푸스문제 0</category>
      <category>파이썬 리스트</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/91</guid>
      <comments>https://dev-sungjun.tistory.com/91#entry91comment</comments>
      <pubDate>Wed, 10 Sep 2025 17:32:40 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 1021번 문제 풀이 - 회전하는 큐</title>
      <link>https://dev-sungjun.tistory.com/90</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1021&quot;&gt;https://www.acmicpc.net/problem/1021&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 N이 주어지면 [1, 2, &amp;hellip;, n-1, n]이 주어지고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두번째 줄에 주어지는 숫자를 3개의 연산을 통해 빼내는 최소 횟수를 구하는 문제입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;연산은 다음이 있습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;첫번째 원소를 뽑아낸다. [1, 2, &amp;hellip;, n-1, n] &amp;rarr; [2, 3, &amp;hellip;, n-1, n]&lt;/li&gt;
&lt;li&gt;왼쪽으로 한칸 이동시킨다. [1, 2, &amp;hellip;, n-1, n] &amp;rarr; [2, 3, &amp;hellip;, n, 1]&lt;/li&gt;
&lt;li&gt;오른쪽으로 한칸 이동시킨다. [1, 2, &amp;hellip;, n-1, n] &amp;rarr; [n, 1, &amp;hellip;, n-2, n-1]&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 이 문제에서 원소를 뽑아내는 것은 1번 연산밖에 없습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 가장 최적의 2,3번 연산을 수행하여 최소 횟수로 원소를 잘 뽑아내면 되는 것입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;최적의 2,3번 연산을 수행하는 방법은 뽑고자 하는 원소의 인덱스를 출력하고 그 인덱스가 0에 가까운지 배열의 길이에 가까운지 비교해서 연산을 돌립니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 [1,2,3,4,5]에서 3을 빼려고 할때&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;왼쪽으로 이동한다면 [1,2,3,4,5] &amp;rarr; [2,3,4,5,1] &amp;rarr; [3,4,5,1,2] 로 2번 이동한 후 첫번째 원소를 빼고,&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;오른쪽으로 이동한다면 [1,2,3,4,5] &amp;rarr; [5,1,2,3,4] &amp;rarr; [4,5,1,2,3] &amp;rarr; [3,4,5,1,2]로 3번 이동한 후 첫번째 원소를 뺍니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 왼쪽으로 이동하는 것이 최소 이동횟수인것입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 뽑으려는 숫자가 0번째 인덱스에 있다면&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;바로 뽑으면 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 정리하면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;뽑으려는 숫자를 배열에 저장해둔다.&lt;/li&gt;
&lt;li&gt;반복문을 통해 배열을 돌며 숫자의 인덱스를 구하고 0번째 인덱스면 바로 뽑고 해당 반복을 끝낸다.&lt;/li&gt;
&lt;li&gt;해당 인덱스 - 0과 해당 인덱스 - len(q)를 통해 더 최적의 연산을 구합니다.&lt;/li&gt;
&lt;li&gt;왼쪽이 더 작다면 2번연산을 인덱스 차이만큼 돌리고 오른쪽이 더 작다면 3번연산을 인덱스 차이만큼 돌립니다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;2번연산을 돌리는 함수는 cnt를 1 증가시키고, 맨 앞의 원소를 빼서 큐의 맨 뒤에 추가하는 연산을 합니다.&lt;/li&gt;
&lt;li&gt;3번 연산을 돌리는 함수는 cnt를 1 증가시키고, 맨 뒤의 원소를 빼서 큐의 맨 앞에 추가하는 연산을 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;돌린 횟수를 출력합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뽑아내야 하는 숫자의 반복문을 돌리니 O(M)이 걸립니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;인덱스를 구하는 연산은 큐의 길이만큼 도니 O(N)이 걸립니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 빼는 2번연산과 3번연산은 원소를 pop하고 append 하는 연산만 수행하기 때문에 O(1)이 걸립니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그것을 인덱스 - 0 혹은 인덱스 - 큐의 길이 만큼 수행하니 O(N/2) 가 걸립니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;반복문 내에서 인덱스 계산하고 연산하니 전체 시간복잡도는 O(MXN)이 나오게 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;N과 M의 최대값은 50이니&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;O(NXM) &amp;rarr; 2500 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 아이디어를 코드로 구현하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import sys
from collections import deque

input = sys.stdin.readline
n, m = map(int, input().split())
# 뽑아야 하는 수 리스트
num_list = map(int, input().split())
# 회전 하는 큐 1 ~ n
q = deque()
for i in range(1, n+1):
    q.append(i)

# 횟수 저장 변수
cnt = 0

# 두번째 연산
def second_command():
    global cnt
    x = q.popleft()
    q.append(x)
    cnt += 1

# 세번째 연산
def third_command():
    global cnt
    x = q.pop()
    q.appendleft(x)
    cnt += 1

# 뽑아내야 하는 수 반복문
for num in num_list:
    # 뽑아내야 하는 수가 0이면 바로 뽑아내고 해당 반복 종료
    if q[0] == num:
        q.popleft()
        continue
    # 0과의 거리와 끝과의 거리 저장
    left = abs(q.index(num) - 0)
    right = abs(q.index(num) - len(q))

    # 0과의 거리가 가깝다면
    if left &amp;lt;= right:
        # 2번째 연산 left 거리만큼 반복
        for _ in range(left):
            second_command()
        q.popleft()
    # 끝과의 거리가 가깝다면
    else:
        # 3번째 연산 right 거리만큼 반복
        for _ in range(right):
            third_command()
        q.popleft()
# 횟수 출력
print(cnt)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>덱</category>
      <category>백준 1021 파이썬</category>
      <category>백준 회전하는 큐 파이썬</category>
      <category>자료구조</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/90</guid>
      <comments>https://dev-sungjun.tistory.com/90#entry90comment</comments>
      <pubDate>Wed, 10 Sep 2025 16:05:00 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 16943번 문제 풀이 - 숫자 재배치</title>
      <link>https://dev-sungjun.tistory.com/89</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/16943&quot;&gt;https://www.acmicpc.net/problem/16943&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A와 B가 주어지는데 A의 숫자들을 해체하여 재조합하여 새로운 수 C를 만드는데&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;C는 B보다 작아야 하고 최대한 크게 만들어야 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;C를 B보다 작게 만들수 없으면 -1을 출력하고 작게 만들 수 있으면 최대값을 출력하는 문제입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각한 아이디어는 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;우선 순열로 A를 재조합해서 만들 수 있는 경우의 배열을 모두 구한다.&lt;/li&gt;
&lt;li&gt;그 배열에서 filter를 사용하여 b 이하인 수들만 남긴다.&lt;/li&gt;
&lt;li&gt;앞자리가 0이 되면 안되므로 A의 길이와 같은 수들만 남긴다.&lt;/li&gt;
&lt;li&gt;배열에 뭐가 남아있으면 max(배열)로 최대값 출력하고 뭐가 없다면 -1을 출력한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 최대는 10의 9승 자리수는 10개 입니다 이 하지만 가장 시간 복잡도가 많이 나오는 것은 123456789로 9자리 수로 이를 순열로 만든다면 9!의 시간복잡도를 가집니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;9! = 362880 입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;filter의 시간복잡도는 O(N)이고 배열을 2번 도니깐 362880 * 2&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;총 362880*3이 되어 100만 정도의 시간복잡도로 문제를 풀게 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 아이디어를 코드로 구현하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;from itertools import permutations

a, b = map(int, input().split())

a = str(a)
arr = list(map(int, a))

length = len(arr)

# A를 해체하고 재조합하여 만들 수 있는 모든 경우의 수 저장
numbers = [int(&quot;&quot;.join(map(str, num))) for num in permutations(arr, length)]

# b보다 작은 수만 남기기
numbers = list(filter(lambda x : x &amp;lt;= b, numbers))

# A의 길이와 같은 것만 남기기 (앞자리에 0이 나오는거 제거)
numbers = list(filter(lambda x : len(str(x)) == length, numbers))

# 수가 있을 경우 최대값 출력, 아닐 경우 -1 출력
if len(numbers):
    print(max(numbers))
else:
    print(-1)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;배운 점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬의 filter 함수 사용법에 대해 알아보았습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;함수 사용은 다음과 같이 사용합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용법 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;filter(function, iterable)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;동작 : iterable의 각 원소에 function(x)를 적용해 True인 것만 남기는 이터레이터를 반환합니다. 그렇기 때문에 list()로 감싸주어 배열로 만들어야 합니다.&lt;/li&gt;
&lt;li&gt;시간복잡도 : O(N)&lt;span&gt;&amp;nbsp;&lt;/span&gt;function(x)의 적용시간 X N(iterable)&lt;/li&gt;
&lt;li&gt;기본 예제&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;makefile&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;numbers = [3, 10, 20, 7]
b = 8

kept_iter = filter(lambda x: x &amp;lt;= b, numbers)  # 이터레이터 반환
kept = list(kept_iter)                         # 리스트 반환

print(kept_iter) # &amp;lt;filter object at 0x104e3d100&amp;gt;
print(kept) # [3,7]
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;function이 None인 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자동으로 bool(x)가 적용되어 참값만 남깁니다.&lt;/li&gt;
&lt;li&gt;0이나 빈 문자열 None등은 False가 나오니 제거 되고 다음과 같이 True 값만 남게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;data = [0, 1, &quot;&quot;, &quot;hi&quot;, None, [], [1], False, True]
cleaned = list(filter(None, data))  # ['', 0, None, [], False 제거 &amp;rarr; ['hi', [1], True]
print(cleaned) # [1, 'hi', [1], True]
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 리스트 컴프리헨션이라는 것으로 훨씬 간단하고 빠르게 filter를 수행할 수 있다고 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예시를 보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# 문법: [식 for 변수 in 이터러블 if 조건]
numbers = [3, 10, 20, 7]
b = 8

# b 이하만 남기기 (filter 대체)
kept = [x for x in numbers if x &amp;lt;= b]  # [3, 7]
plus_one = [x+1 for x in numbers if x &amp;lt;= b] # [4, 8]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앞의 식은 맨 뒤의 조건으로 걸러지는 요소들에 특정 연산, 여기서는 +1 연산을 해주는 역할이고 *2 해서 2배로 늘리는 것도 가능합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 변수 in 이터러블은 이터러블을 반복도는 것이고 if 조건은 특정 조건이 참인 요소들을 거르는 문법입니다.&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>백준 16943 파이썬</category>
      <category>백준 숫자재배치 파이썬</category>
      <category>파이썬 filter</category>
      <category>파이썬 리스트 컴프리헨션</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/89</guid>
      <comments>https://dev-sungjun.tistory.com/89#entry89comment</comments>
      <pubDate>Sat, 6 Sep 2025 00:08:35 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 1527번 문제 풀이 - 금민수의 개수</title>
      <link>https://dev-sungjun.tistory.com/88</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1527&quot;&gt;https://www.acmicpc.net/problem/1527&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;금민수는 4와 7로만 이루어진 숫자를 의미하는데 주어지는 A이상 B이하의 수 중에 금민수가 몇 개 있는지 출력하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 그냥 A부터 B까지 전부 반복문 돌리면서 4와 7로만 이루어진 수일때 cnt+1을 해주려 하였지만 최대가 10억이기 때문에 최악의 경우 10억번 연산을 돌기 때문에 시간초과가 날 것이였습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 금민수 배열을 미리 만들어둘 때 이 배열은 개수가 적을것이라는 생각이 들었고, 10억 아래의 금민수는 1000개 정도밖에 없었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이 배열을 순회하며 A와 B사이에 있는 수라면 cnt +1을 하는 방식으로 풀기로 했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아이디어를 정리하면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;금민수 배열을 만든다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;10을 곱하고 4를 더하는 재귀함수를 호출한다.&lt;/li&gt;
&lt;li&gt;10을 곱하고 7을 더하는 재귀함수를 호출한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;금민수 배열을 순회하며 범위에 포함되는 수라면 cnt+1을 한다.&lt;/li&gt;
&lt;li&gt;cnt를 출력한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;입니다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도는 금민수를 만드는 연산에서 함수를 1000번정도 호출하니 1000&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1000개정도의 배열을 한번 순회하니 O(N)으로 1000정도&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 2000 정도의 시간이 걸립니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 아이디어를 코드로 구현하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;a,b= map(int, input().split())

result = []

def generate_lucky_numbers(current):

    if current &amp;gt; 10**9:
        return

    if current != 0:
        result.append(current)

    generate_lucky_numbers(current * 10 + 4)
    generate_lucky_numbers(current * 10 + 7)

generate_lucky_numbers(0)

cnt = 0
for x in result:
    if a&amp;lt;=x&amp;lt;=b:
        cnt += 1

print(cnt)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;느낀 점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금민수를 미리 만들어놓는 아이디어를 생각했지만 이것을 코드로 어떻게 구현해서 미리 만들어야 할지에 대해 시간이 오래 걸렸습니다. 곱하기 10하고 4나 7을 더하는 것은 알겠지만 모든 경우의 수를 다 계산하는 재귀함수를 만들기가 어려웠습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;재귀함수에 익숙해지도록 문제를 많이 풀어야 할 것이라는 생각이 들었습니다.&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>백준 1527 파이썬</category>
      <category>백준 금민수의 개수 파이썬</category>
      <category>브루트포스</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/88</guid>
      <comments>https://dev-sungjun.tistory.com/88#entry88comment</comments>
      <pubDate>Fri, 5 Sep 2025 11:34:22 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 15686번 문제 풀이 - 치킨배달</title>
      <link>https://dev-sungjun.tistory.com/87</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15686&quot;&gt;https://www.acmicpc.net/problem/15686&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 치킨집에서 가게유지비용 때문에 남길 치킨집을 m개로 정했을 때 모든 집에서 치킨집까지의 거리가 최소가 되는 집을 구하고, 최소거리를 출력하는 문제입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;집과 치킨집과의 거리는 집과 치킨집의 행과 열의 차이를 더한 것으로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;|치킨집x-집x| + |치킨집y-집y|&amp;nbsp;&lt;/b&gt;&lt;/span&gt;입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적의 치킨집이 뭔지 찾으려면 어떻게 해야할까 생각하다가 딱히 규칙이 보이지 않았고 전부 탐색을 해봐야겠다고 생각했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 치킨집의 좌표와, 집의 좌표를 저장해두고 전체 치킨집에서 m개를 뽑는 모든 경우의 수를 탐색하여 최소거리가 나오는 것을 출력하려는 아이디어를 세웠습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나온 아이디어는 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;입력에서 집의 좌표와 치킨집의 좌표를 저장한다.(1과 2가 나오면 저장배열에 저장)&lt;/li&gt;
&lt;li&gt;전체 치킨집에서 m개를 뽑는 모든 경우의 수를 탐색한다.&lt;/li&gt;
&lt;li&gt;m개를 뽑았을 경우에 이 경우가 최소 치킨거리인지 확인한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;각 집에서 고른 치킨집까지 가장 적게 걸리는 거리를 저장&lt;/li&gt;
&lt;li&gt;각 집에서 치킨집까지 걸리는 거리를 전부 더해서 최소값인지 판단해서 저장&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;최소 치킨거리를 출력한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전부 탐색하는 방법을 선택했기 때문에 아이디어를 떠올리며 시간복잡도를 계산했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 치킨집은 최대 13개이고 이중에서 m개를 선택하는 것인데 고르는 경우의 수는 조합의 경우의 수인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;13Cm&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이것을 최대로 만드는 m값은 6또는 7인데 1716이 나옵니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이제 최소거리를 측정해야하는데 집의 거리는 2N개로 100개입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 치킨집은 7일 때 가장 많아집니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 정리하면 1716번의 경우에 100번의 집을 탐색하고 치킨집은 7번이기 때문에&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1716 X 100 X 7이 되어서 1,201,200이 나오게 되고 이것은 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 아이디어를 코드로 구현하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;python&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# 현재 뽑은 치킨집 좌표에서 가장 최소거리 뽑아내는 함수
def update_min_distance(picked_chicken):
    global house_length
    # 치킨집과의 거리 저장 배열
    chicken_house_distance = [int(1e9)] * house_length

    for i in range(house_length):
        (hy, hx) = house_coordinate[i] # 집 좌표 뽑기

        for j in picked_chicken:
            (cy, cx) = chicken_coordinate[j] # 치킨 좌표 뽑기
						
	    # 집에서 치킨집까지의 최소거리 저장
            chicken_house_distance[i] = min(abs(hy-cy) + abs(hx-cx), chicken_house_distance[i])

    return sum(chicken_house_distance) # 총 치킨거리 리턴

# 전체 치킨집 중 m개 치킨집 빼기 위한 재귀함수
def recur(start):
    global answer
    global chicken_length

    # m개 뽑았으면 최소값 리턴
    if len(picked) == m:
        answer = min(answer, update_min_distance(picked))
        return

    # 남아있는 거
    remain = chicken_length-start
    # 필요한 거
    need = m - len(picked)
    # 남아있는거보다 필요한게 더 많으면 리턴
    if remain &amp;lt; need:
        return

    # m개 배열에 넣는 재귀함수
    for i in range(start, chicken_length):
        picked.append(i)
        recur(i + 1)
        picked.pop()

import sys
input = sys.stdin.readline

n, m = map(int, input().split())

# 치킨집 좌표
chicken_coordinate = []
# 집 좌표
house_coordinate = []

for i in range(n):
    temp = list(map(int, input().split()))

    for j in range(n):
        if temp[j] == 1: # 집 좌표 저장
            house_coordinate.append((i,j))
        elif temp[j] == 2: # 치킨집 좌표 저장
            chicken_coordinate.append((i,j))

house_length = len(house_coordinate)
chicken_length = len(chicken_coordinate)

picked = []
answer = int(1e9)

recur(0)
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;느낀 점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 Combination을 써서 조합으로 하면 편하겠다는 생각을 했지만 조합 사용법에 대해 잘 몰라서 재귀함수로 전체 치킨집중에 m개를 뽑는 것을 구현했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;재귀함수를 구현하면서도 어떻게 구현해야 모든 경우를 다 탐색할 수 있는지 떠올리는 것이 어려웠고, 오랜 시간이 걸렸습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 다른 사람이 Combination을 활용하여 푼 풀이를 봤습니다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import sys
from itertools import combinations

input = sys.stdin.readline

n, m = map(int, input().split())
city = list(list(map(int, input().split())) for _ in range(n))
result = 999999
house = []      # 집의 좌표
chick = []      # 치킨집의 좌표

for i in range(n):
    for j in range(n):
        if city[i][j] == 1:
            house.append([i, j])
        elif city[i][j] == 2:
            chick.append([i, j])

for chi in combinations(chick, m):  # m개의 치킨집 선택
    temp = 0            # 도시의 치킨 거리
    for h in house: 
        chi_len = 999   # 각 집마다 치킨 거리
        for j in range(m):
            chi_len = min(chi_len, abs(h[0] - chi[j][0]) + abs(h[1] - chi[j][1]))
        temp += chi_len
    result = min(result, temp)

print(result)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콤비네이션을 사용해서 코드가 엄청 간결했고, 보기 편했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 조합을 사용하는 방법에 대해 공부를 해봐야겠다고 느꼈습니다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;조합과 순열&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 파이썬은 itertools의 combinations 함수를 제공합니다. 사용 예시는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;combinations(iterable, r)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;from itertools import combinations

# 예시 리스트
data = [1, 2, 3, 4]

# 2개씩 뽑는 조합
result = list(combinations(data, 2))
print(result) # [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 중복을 허용하지 않아 (1,1) 같은 결과는 나오지 않고, 순서를 무시하여 (1,2)와 (2,1)은 나오지가 않습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 반환값은 tuple을 반환해서 이것을 배열로 바꾸려면 list()를 씌워야 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 첫번째 인자에 들어갈 수 있는 값은 반복 가능한 값 이라면 전부 가능합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;리스트, 문자열, 튜플, 집합, 딕셔너리 등이 들어갈 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;딕셔너리는 key만 빼서 반복을 돌립니다. 예시를 들면 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;print(list(combinations({&quot;a&quot;: 1, &quot;b&quot;: 2, &quot;c&quot;: 3}, 2)))
# [('a', 'b'), ('a', 'c'), ('b', 'c')]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;combinations는 중복을 허용하지 않는 조합인데 중복을 허용하는 조합도 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;combinations_with_replacement(iterable, r)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 함수도 combinations()와 들어가는 인자는 동일합니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;from itertools import combinations_with_replacement

data = [1, 2, 3]

result = list(combinations_with_replacement(data, 2))
print(result) # [(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러면 (1,1)과 (2,2) 같은 중복을 허용하는 값도 나오는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 순열 사용법에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;순열은 다음 함수를 사용합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;permutations(iterable, r)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;from itertools import permutations

data = [1, 2, 3]
result = list(permutations(data, 2))
print(result) # [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;순열은 순서를 신경써서 출력합니다. 그래서 (1,2)와 (2,1)이 있는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이 순열은 중복을 허용하지 않습니다. 만약 중복이 허용되는 함수를 쓰려면 Product 함수를 사용해야합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;마지막으로 product 함수 사용법에 대해 알아보겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;product(iterable, repeat=N)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;from itertools import product

data = [1, 2, 3]
result = product(data, repeat=2)
print(list(result))
# [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이것도 마찬가지로 인자는 비슷하게 들어가는데요, 두번째 인자에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;repeat=N&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 써주어야 하는 점이 약간 다릅니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;product()&lt;/b&gt;&lt;/span&gt;는 중복과 순서를 모두 허용하여 출력하여 (1,1) 같은 것도 나오고 (1,2), (2,1) 같은 것도 출력되는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 각 함수의 특징에 대해 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;table style=&quot;color: #000000; text-align: start; border-collapse: collapse; width: 47.093%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.0465%;&quot;&gt;&lt;b&gt;함수종류&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 8.37207%;&quot;&gt;&lt;b&gt;순서&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 7.67442%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;중복&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.0465%;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;combinations&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 8.37207%;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 7.67442%;&quot;&gt;X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.0465%;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;combinations_with_replacement&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 8.37207%;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 7.67442%;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.0465%;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;permutations&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 8.37207%;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 7.67442%;&quot;&gt;X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.0465%;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;product&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 8.37207%;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 7.67442%;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>구현</category>
      <category>백준 15686 파이썬</category>
      <category>백준 치킨배달 파이썬</category>
      <category>조합과 순열</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/87</guid>
      <comments>https://dev-sungjun.tistory.com/87#entry87comment</comments>
      <pubDate>Sat, 23 Aug 2025 17:18:42 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 14891번 문제 풀이 - 톱니바퀴</title>
      <link>https://dev-sungjun.tistory.com/86</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14891&quot;&gt;https://www.acmicpc.net/problem/14891&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 톱니바퀴가 맞물려서 회전하고 다 회전했을 때의 12시 방향의 극이 어떤지에 따라 1,2,4,8을 더해서 값을 출력하는 문제입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;12시 방향의 극이 어떤지에 따라 값을 더하는 구성을 살펴보면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1번 톱니바퀴 : N일 경우 0을 더하고, S일 경우 1을 더합니다.&lt;/li&gt;
&lt;li&gt;2번 톱니바퀴 : N일 경우 0을 더하고, S일 경우 2를 더합니다.&lt;/li&gt;
&lt;li&gt;3번 톱니바퀴 : N일 경우 0을 더하고, S일 경우 4를 더합니다.&lt;/li&gt;
&lt;li&gt;4번 톱니바퀴 : N일 경우 0을 더하고, S일 경우 8을 더합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;톱니바퀴는 시계방향 혹은 반시계 방향으로 한칸씩 회전을 하는데&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;맞닿아 있는 극이 서로 다르다면 맞닿은 톱니바퀴가 반대방향으로 회전하고 극이 같다면 맞닿아 있는 톱니바퀴는 회전하지 않습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음 그림의 상태에 있는 톱니 바퀴가 있다고 가정하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1294&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTZ4cC/btsP49rRWma/NBkcO69sozpxfgnPBjRZWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTZ4cC/btsP49rRWma/NBkcO69sozpxfgnPBjRZWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTZ4cC/btsP49rRWma/NBkcO69sozpxfgnPBjRZWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTZ4cC%2FbtsP49rRWma%2FNBkcO69sozpxfgnPBjRZWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1294&quot; height=&quot;324&quot; data-origin-width=&quot;1294&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3번 톱니바퀴가 시계 방향으로 회전한다고 하고 왼쪽 맞닿아 있는 극은 S극, 오른쪽 맞닿아 잇는 극은 N극입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2번 톱니바퀴가 3번 톱니바퀴랑 맞닿아 있는 극은 S로 같기 때문에 2번 톱니바퀴는 회전하지 않습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4번 톱니바퀴와 3번 톱니바퀴랑 맞닿아 있는 극은 S, N으로 다르기 때문에 4번 톱니바퀴는 시계방향의 반대방향인 반시계 방향으로 회전합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;맞닿아 있는 톱니바퀴의 회전이 끝나면 3번 톱니바퀴를 시계 방향으로 회전시킵니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 다음 결과가 나오게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bqu8X/btsP2JaboRr/fJeIlr6nUpv9s76vygwvUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bqu8X/btsP2JaboRr/fJeIlr6nUpv9s76vygwvUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bqu8X/btsP2JaboRr/fJeIlr6nUpv9s76vygwvUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBqu8X%2FbtsP2JaboRr%2FfJeIlr6nUpv9s76vygwvUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1306&quot; height=&quot;326&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 예시에서는 2번이 회전하지 않았기 때문에 1번이 회전하지 않지만&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt; 만약에 2번 톱니바퀴가 회전하게 된다면 1,3번 톱니바퀴를 보고 회전을 하도록 하는데&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;3번은 이미 도는게 예약이 되어있기 때문에 넘어가고 1번 톱니바퀴가 도는지 확인하고 돌릴지 말지 결정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이 문제를 해결할 아이디어는 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;K만큼 반복문을 돌며 회전하도록 합니다.&lt;/li&gt;
&lt;li&gt;n번 톱니바퀴를 특정 방향으로 돌리는 함수를 호출합니다.&lt;/li&gt;
&lt;li&gt;함수 내부 로직은 다음과 같습니다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;왼쪽 톱니바퀴를 돌리는 &lt;b&gt;예약이 되어있지 않고&lt;/b&gt;, &lt;b&gt;톱니바퀴가 1~3번 내&lt;/b&gt;에 있으며, 현재 톱니바퀴와 &lt;b&gt;맞닿아 있는 극이 다르다면&lt;/b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(왼쪽의 2번 인덱스 != 현재의 6번인덱스)&lt;/b&gt; &lt;/span&gt;왼쪽 톱니바퀴를 반대로 회전 시키는 함수를 호출합니다.&lt;/li&gt;
&lt;li&gt;오른쪽 톱니바퀴를 돌리는 &lt;b&gt;예약이 되어있지 않고&lt;/b&gt;, &lt;b&gt;톱니바퀴가 2~4번 내&lt;/b&gt;에 있으며, 현재 톱니바퀴와 &lt;b&gt;맞닿아 있는 극이 다르다면&lt;/b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(=오른쪽의 6번 인덱스 != 현재의 2번인덱스)&lt;/b&gt; &lt;/span&gt;오른쪽 톱니바퀴를 반대로 회전 시키는 함수를 호출합니다.&lt;/li&gt;
&lt;li&gt;마지막에 현재 톱니바퀴를 회전 시킵니다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;시계 방향인 경우엔 인덱스에 +1을 해주고 %8을 해줍니다.&lt;/li&gt;
&lt;li&gt;반시계 방향인 경우엔 인덱스에 -1을 해주고 %8을 해줍니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;톱니바퀴가 다 돌았으면 12시 방향의 극&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(=각 톱니바퀴의 0번째 인덱스)&lt;/b&gt;&lt;/span&gt;을 확인하고 S면 톱니바퀴에 따른 값&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(=2^(톱니바퀴번호-1))&lt;/b&gt;&lt;/span&gt;을 더해주면 됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 회전 횟수 K는 100입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 함수 내부에서는 조건을 확인해서 내부 재귀함수 호출하는게 많아야 3번입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 마지막에 톱니 바퀴를 회전시키는 것은 8개의 극을 한번씩 순회합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 최종 시간 복잡도는 100X3X8이기 때문에 24,000으로 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 아이디어를 코드로 구현하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline

cogwheels = []

# 톱니바퀴 1~4의 극 정보들
for _ in range(4):
    temp = list(map(int, input().rstrip()))
    cogwheels.append(temp)

k = int(input())
# 회전 명령들
rotates = []
for _ in range(k):
    cog_num, direction = map(int, input().split())
    rotates.append((cog_num, direction))

# 톱니바퀴 회전 함수
def cog_rotate(cog_num, direction):
    # 톱니바퀴 돌리기로 예약
    visited[cog_num] = True
    # 왼쪽 오른쪽 톱니바퀴 저장
    left, right = cog_num-1, cog_num+1
    
    # 왼쪽이 1~3번중에 있고, 예약되지 않았을때
    if left &amp;gt;= 0 and not visited[left]:
        # 왼쪽과 현재 톱니바퀴가 맞닿아 있는 극이 다를 때
        if cogwheels[cog_num][6] != cogwheels[left][2]:
            # 방향 전환
            if direction == 1:
                new_direction = -1
            else:
                new_direction = 1
            # 왼쪽 톱니바퀴 반대방향으로 돌리는 함수 호출
            cog_rotate(left, new_direction)

    # 오른쪽이 2~4번중에 있고, 예약되지 않았을때
    if right &amp;lt;= 3 and not visited[right]:
        # 오른쪽과 현재 톱니바퀴가 맞닿아 있는 극이 다를 때
        if cogwheels[cog_num][2] != cogwheels[right][6]:
            # 방향 전환
            if direction == 1:
                new_direction = -1
            else:
                new_direction = 1
            # 오른쪽 톱니바퀴 반대방향으로 돌리는 함수 호출
            cog_rotate(right, new_direction)
    
    # 톱니바퀴 시계 혹은 반시계 방향으로 돌리는 부분
    temp = [0] * 8
    for i in range(8):
        temp[(i+direction)%8] = cogwheels[cog_num][i]

    cogwheels[cog_num] = temp

# 회전 명령들 수행
for element in rotates:
    # 회전 예약 여부 체크
    visited = [False] * 4
    # 현재 톱니바퀴 시계 혹은 반시계 방향으로 회전
    (cog_num, direction) = element
    cog_rotate(cog_num-1, direction)

# 12시방향의 극이 S인지 확인하여 결과값에 2의 제곱 더해주기
answer = 0
for i in range(4):
    if cogwheels[i][0] == 1:
        answer += (2**i)

# 정답 출력
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;느낀 점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 문제는 좀 쉬운 문제라고 느껴졌습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 다른 블로그를 참고하지 않고 혼자 힘으로 풀수 있었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 함수 내부에서 조건문을 설정하는 부분에서 방문여부를 체크하지 못하여 재귀함수를 무한루프를 돌리는 문제가 발생했었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아이디어를 떠올리고 이것을 코드로 구현하는데 시간이 많이 걸렸고 구현 문제를 더 많이 풀어서 아이디어를 신속정확하게 코드로 구현할 수 있게 노력해야겠다고 느꼈습니다.&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>구현</category>
      <category>백준 14891 파이썬</category>
      <category>백준 톱니바퀴 파이썬</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/86</guid>
      <comments>https://dev-sungjun.tistory.com/86#entry86comment</comments>
      <pubDate>Fri, 22 Aug 2025 19:55:18 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 14499번 문제 풀이 - 주사위굴리기</title>
      <link>https://dev-sungjun.tistory.com/85</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14499&quot;&gt;https://www.acmicpc.net/problem/14499&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 주사위를 동,서,북,남 방향으로 굴렸을 때 윗면의 눈금을 출력하는 문제입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주사위는 처음 시작할 때 모든 면이 0입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;굴릴때 격자가 0이라면 주사위 밑면의 눈금이 격자로 복사되고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;굴릴때 격자가 0이 아니면 격자의 눈금이 주사위로 복사되고 격자의 눈금은 0이 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 지도의 바깥으로 나가면 아무런 동작을 하지 않습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 제가 생각했던 아이디어는 다음과 같습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주사위의 윗면이 1일때 동서남북으로 굴릴때 밑면의 주사위 눈금이 뭐가 나오는지 확인하는 것입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;상상으로는 안됐기 때문에 종이로 전개도를 그리고 접어서 확인해봤습니다&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;288&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1wrvW/btsP2FjZ6uv/kxnSgn0rrIAUULfgaYKwaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1wrvW/btsP2FjZ6uv/kxnSgn0rrIAUULfgaYKwaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1wrvW/btsP2FjZ6uv/kxnSgn0rrIAUULfgaYKwaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1wrvW%2FbtsP2FjZ6uv%2FkxnSgn0rrIAUULfgaYKwaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;146&quot; height=&quot;193&quot; data-origin-width=&quot;288&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나온 결과는 다음과 같았습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;# dice_direction = {
#     1 : [3,4,2,5],
#     2 : [3,4,6,1],
#     3 : [6,1,2,5],
#     4 : [5,2,1,6],
#     5 : [3,4,1,6],
#     6 : [3,4,5,2]
# }
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제 동서남북 방향은 다구했고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;반대면 = 7-현재면&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;으로 구할 수 있었기 때문에 바닥면의 눈금을 최신화 시키고 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;7-바닥면&lt;/b&gt;&lt;/span&gt; 해서 출력하면 될거라고 생각했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;근데 여기서 문제가 좌우로 굴렸을 경우 제가 구했던 방향대로 주사위 눈금이 안나오는 것이 문제였습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;그래서 답이 다르게 나왔고, 결국 답을 찾아봤습니다 ㅎㅎ&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;찾아본 결과 동,서,북,남으로 굴릴 때 주사위의 눈금 위치가 어떻게 바뀌는지에 대한 규칙이 있었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;위, 뒤, 오른쪽, 왼쪽, 앞쪽, 바닥&lt;/b&gt;을 &lt;b&gt;1,2,3,4,5,6&lt;/b&gt;으로 하고 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;동쪽&lt;/b&gt;&lt;/span&gt;으로 움직이면 [1,2,3,4,5,6]이 [3,2,6,1,5,4]로 바뀌는 것처럼 규칙이 있었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 규칙을 적용하여 굴릴때마다 주사위 눈금의 위치가 변하는 것을 구할수 있었고 저 배열의 0번째 인덱스를 출력하고, 5번째 인덱스를 최신화 하면 위를 출력하고 바닥을 최신화 할 수 있었습니다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 코드의 K번만큼 반복하기 때문에 O(K) K = 1000이므로 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 아이디어를 코드로 구현하면 다음과 같습니다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;n, m, x, y, k = map(int, input().split())

board = []
# 동 서 북 남
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]

dice = [0, 0, 0, 0, 0, 0]

def turn(dir):
    global dice
    a, b, c, d, e, f = dice
    if dir == 1: #동
        dice = [d, b, a, f, e, c]

    elif dir == 2: #서
        dice = [c, b, f, a, e, d]

    elif dir == 3: #북
        dice = [e, a, c, d, f, b]

    else:
        dice = [b, f, c, d, a, e]

for i in range(n):
    board.append(list(map(int, input().split())))

moves = list(map(int, input().split()))

nx, ny = x, y
for move in moves:
    nx += dx[move-1]
    ny += dy[move-1]
		
		# 밖으로 나갈 때
    if not ((0&amp;lt;=ny&amp;lt;n) and (0&amp;lt;=nx&amp;lt;m)):
		    # 움직이기 전 상태로 돌리고
        nx -= dx[move-1] 
        ny -= dy[move-1]
        continue # 아무 동작도 하지 않음
    turn(move) # 주사위 굴리기
    # 격자가 0 일때
    if board[nx][ny] == 0:
        board[nx][ny] = dice[-1]
    # 격자가 0이 아닐때
    else:
        dice[-1] = board[nx][ny]
        board[nx][ny] = 0

    print(dice[0])&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;느낀 점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이디어 한번 잘못 생각하고 코드까지 다 구현하면 돌아가기가 힘들다는 것을 깨달았습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 아이디어 구현하는데 집중력을 다 써서 다른 방법을 떠올리기가 쉽지 않았습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아이디어가 확실한지 반례는 없는지 확인까지 다 해보고 그다음에 코드 구현을 들어가야 겠다고 느꼈습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래 코드는 제가 구현했다가 1번 예제부터 안나와서 주석처리한 코드입니다..&lt;/p&gt;
&lt;pre class=&quot;python&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# import sys
# input = sys.stdin.readline
#
# n, m, x, y, k = map(int, input().split())
#
# # 격자
# graph = [list(map(int, input().split())) for _ in range(n)]
# # 이동할 방향 리스트
# moves = list(map(int, input().split()))
#
# # 윗면 기준 다음 방향으로 이동했을 때 밑면
# dice_direction = {
#     1 : [0,3,4,2,5],
#     2 : [0,3,4,6,1],
#     3 : [0,6,1,2,5],
#     4 : [0,5,2,1,6],
#     5 : [0,3,4,1,6],
#     6 : [0,3,4,5,2]
# }
#
# # 현재 주사위 눈금 현황
# current_dice = {
#     1 : 0,
#     2 : 0,
#     3 : 0,
#     4 : 0,
#     5 : 0,
#     6 : 0
# }
#
# # 동, 서, 북, 남
# dy = [100000, 0, 0, -1, 1]
# dx = [100000, 1, -1, 0, 0]
#
#
# def moving_dice(move):
#     global current_top
#     global y
#     global x
#
#     print(current_dice)
#     # 다음 좌표
#     ny = y + dy[move]
#     nx = x + dx[move]
#
#     # 벗어날 경우 아무동작도 하지 않음
#     if not (0&amp;lt;=ny&amp;lt;n) and (0&amp;lt;=nx&amp;lt;m):
#         return
#
#     # 이동 후 현재 밑면
#     # print(dice_direction[current_top])
#     # print(move)
#
#     # 현재 밑면 : 현재 윗면 기준으로 아랫면 구하기
#     current_bottom = dice_direction[current_top][move]
#     # print(f&quot;current_top : {current_top}, move : {move}&quot;)
#     # print(current_bottom)
#     # print(f&quot;current_top : {current_top}, current_bottom : {current_bottom}, y : {y}, x: {x}, ny : {ny}, nx : {nx}, move : {move}&quot;)
#     # print(&quot;현재 주사위의 눈금&quot;)
#
#
#     # 격자가 0이 아닐 경우
#     if graph[ny][nx] != 0:
#         # 주사위의 밑면을 격자로 복사한 후
#         current_dice[current_bottom] = graph[ny][nx]
#         # 격자는 0으로 만든다.
#         graph[ny][nx] = 0
#     # 격자가 0일 경우
#     else:
#         # 주사위의 눈금이 격자로 복사된다.
#         graph[ny][nx] = current_dice[current_bottom]
#
#     current_top = 7-current_bottom
#     # print(f&quot;current_top : {current_top}, current_bottom : {current_bottom}, y : {y}, x: {x}, ny : {ny}, nx : {nx}, move : {move}&quot;)
#     y = ny
#     x = nx
#     print(current_dice[current_top])
#
# current_top = 1
# for move in moves:
#     moving_dice(move)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고한 블로그&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hongcoding.tistory.com/128&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hongcoding.tistory.com/128&lt;/a&gt;&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>구현</category>
      <category>백준 14499번 파이썬</category>
      <category>백준 주사위굴리기</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/85</guid>
      <comments>https://dev-sungjun.tistory.com/85#entry85comment</comments>
      <pubDate>Thu, 21 Aug 2025 19:13:42 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 15685번 문제 풀이 - 드래곤 커브</title>
      <link>https://dev-sungjun.tistory.com/84</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15685&quot;&gt;https://www.acmicpc.net/problem/15685&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 각 세대의 드래곤 커브가 격자에 그려집니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 때 1X1의 정사각형의 네 꼭짓점이 드래곤 커브의 일부인 정사각형 개수를 구하는 문제입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;드래곤 커브는 시작점, 방향, 세대로 그릴 수 있는데요&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;시작점은&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;y,x 좌표로 이루어져 있고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;방향은&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;0 : &amp;rarr; (x가 증가하는 방향)&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1 : &amp;uarr; (y가 감소하는 방향)&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2 : &amp;larr; (x가 감소하는 방향)&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3 : &amp;darr; (y가 증가하는 방향)&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;세대가 좀 복잡한데&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CqXhI/btsP1mkf19N/OswnNpzalF9Z1kPMEKc3r1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CqXhI/btsP1mkf19N/OswnNpzalF9Z1kPMEKc3r1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CqXhI/btsP1mkf19N/OswnNpzalF9Z1kPMEKc3r1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCqXhI%2FbtsP1mkf19N%2FOswnNpzalF9Z1kPMEKc3r1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1298&quot; height=&quot;906&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이렇게 끝점을 기준으로 90도 꺾어서 이전 세대의 커브를 붙이면 세대가 올라가는 형식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;처음에 세대가 3세대까지인줄 알고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3NcSX/btsP0k1Nz8a/BlDKoqENtbdo3c84YpHkH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3NcSX/btsP0k1Nz8a/BlDKoqENtbdo3c84YpHkH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3NcSX/btsP0k1Nz8a/BlDKoqENtbdo3c84YpHkH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3NcSX%2FbtsP0k1Nz8a%2FBlDKoqENtbdo3c84YpHkH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;315&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음처럼 3세대까지 좌표를 구해서 격자에 True 표시해두고 정사각형의 4점이 전부 겹치는 곳을 찾을라고 했으나, 10세대까지 있는 것을 봤습니다. 그래서 규칙성을 찾으려 해봤지만 찾지 못해 다른 블로그를 참고 하였습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다른 블로그에서는 좌표가 아닌 방향으로 규칙을 찾았었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XFdYd/btsPZTDoWFD/PIVXifQdcawZAkOKHfcrrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XFdYd/btsPZTDoWFD/PIVXifQdcawZAkOKHfcrrK/img.png&quot; data-alt=&quot;https://velog.io/@ckstn0778/%EB%B0%B1%EC%A4%80-15685%EB%B2%88-%EB%93%9C%EB%9E%98%EA%B3%A4-%EC%BB%A4%EB%B8%8C-1-Python&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XFdYd/btsPZTDoWFD/PIVXifQdcawZAkOKHfcrrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXFdYd%2FbtsPZTDoWFD%2FPIVXifQdcawZAkOKHfcrrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1302&quot; height=&quot;430&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@ckstn0778/%EB%B0%B1%EC%A4%80-15685%EB%B2%88-%EB%93%9C%EB%9E%98%EA%B3%A4-%EC%BB%A4%EB%B8%8C-1-Python&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 규칙이 있었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이전 세대를 reverse하고 방향에 1씩 더해서 붙이면 다음세대가 된다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예시를 들면 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0세대 : 0&lt;/li&gt;
&lt;li&gt;1세대 : 0 / 1(0+1)&lt;/li&gt;
&lt;li&gt;2세대 : 0,1 / 2,1 (1+1, 0+1)&lt;/li&gt;
&lt;li&gt;3세대 : 0,1,2,1 / 2,3,2,1(1+2, 2+1, 1+1, 0+1)&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 세대별 드래곤커브를 구합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 정사각형이 가능한것은 0,0부터 오른쪽, 아래, 오른쪽아래대각선을 순차적으로 탐색하며 4꼭짓점이 모두 드래곤커브의 일부라면 결과값에 +1을 해줍니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;정리하면 아이디어는 다음과 같습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;시작점, 방향, 세대에 따른 드래곤 커브를 격자에 그린다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;그리는 방법은 이전세대를 reverse하고&lt;/li&gt;
&lt;li&gt;reverse한거를 +1하고 4로 나머지연산하여 배열에 저장한다.&lt;/li&gt;
&lt;li&gt;그리고 배열을 돌며 드래곤 커브인 부분을 격자에 표시한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;0,0부터 시작하며 정사각형이 나오면 결과에 +1한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 아이디어의 시간복잡도는 드래곤커브의 개수는 20개이고 최대 세대는 10개입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 20 X 2^10 = 20480정도 격자를 돌며 드래곤커브가 거치는 구간에 선을 그어줍니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 마지막 정사각형이 몇개인지 찾는 것은 X, Y 좌표를 돌며 하는건데 각각 최대값이 100이기 때문에 100 X 100 하면 10000이 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 20,000 + 10,000 &amp;rarr; 30,000 으로 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline

n = int(input())

dy = [0, -1, 0, 1]
dx = [1, 0, -1, 0]

graph = [[0] * 101 for _ in range(101)]

for _ in range(n):
    x, y, d, g = map(int, input().split())

    curve = [d]
    graph[y][x] = 1

    for i in range(g):
        for j in range(len(curve)-1, -1, -1):
            curve.append((curve[j] + 1) % 4)

    for k in curve:
        y += dy[k]
        x += dx[k]

        if y &amp;lt; 0 or y &amp;gt; 100 or x &amp;lt; 0 or x &amp;gt; 100:
            continue

        graph[y][x] = 1

answer = 0

for i in range(100):
    for j in range(100):
        if graph[i][j] and graph[i+1][j] and graph[i][j+1] and graph[i+1][j+1]:
            answer += 1

print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>구현</category>
      <category>백준 15685번 파이썬</category>
      <category>백준 드래곤커브 파이썬</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/84</guid>
      <comments>https://dev-sungjun.tistory.com/84#entry84comment</comments>
      <pubDate>Wed, 20 Aug 2025 19:19:37 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 백준 17144번 문제 풀이 - 미세먼지 안녕!</title>
      <link>https://dev-sungjun.tistory.com/83</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 링크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17144&quot;&gt;https://www.acmicpc.net/problem/17144&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문제 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 특정 시간이 지난후에 남아있는 미세먼지 양이 얼마나 되는지 출력하면 되는 문제입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;미세먼지는 주변 상하좌우 칸으로 //5 만큼 해서 이동합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;상하좌우로 갈 때 맵을 벗어나거나 공기청정기가 있다면 확산하지 않습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(1,1)에 있는 미세먼지는 (0,1), (1,0), (2,1), (1,2)가 가능하여 4방향으로 확산하고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(0,0)에 있는 미세먼지는 (1,0)과 (0,1)로 확산합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 또 중요한것은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;미세먼지는 누적되서 확산하는 것이 아닌 동시에 확산되는 점&lt;/b&gt;&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이게 무슨 말이냐 하면&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음 그림을 보면서 설명하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mh605/btsPYOuMUmD/hg63MuLbTj9dp4CQSdDy8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mh605/btsPYOuMUmD/hg63MuLbTj9dp4CQSdDy8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mh605/btsPYOuMUmD/hg63MuLbTj9dp4CQSdDy8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmh605%2FbtsPYOuMUmD%2Fhg63MuLbTj9dp4CQSdDy8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1288&quot; height=&quot;430&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(0,1) 에는 30이 있습니다. 30이 확산될 칸은 (0,0), (0,2), (1,1)이 있는데요 //5 하면 각 칸마다 미세먼지가 6씩 확산됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존 칸에는 확산된만큼 빼줍니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 (0,0)에 6, (0,1)에 12, (0,2)에 13, (1,1)에 16이 됩니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;6 12 13
-1 16 0
-1 0 20
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 다음 미세먼지가 있던 (0,2)로 이동하면 7에 6이 누적되어 13이 되었다고 //5 해서 2가 이동하는 것이 아닙니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;한꺼번에 퍼지기 때문에 (0,1)과 (1,2)에 1씩 확산되고 (0,2)에는 2가 빠지는 것입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;정리하면 30은 주변 세 칸에 6씩 확산시키고 원래 자신은 18이 빠지는거고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;7은 주변 두 칸에 1씩 확산시키고 자신은 2가 빠지는 거고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;10은 공기청정기를 제외한 주변 세 칸에 2씩 확산시키고 자신은 6이 빠지는 것입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 공기청정기는 높이가 2인데 위쪽 청정기는 반시계 방향으로 순환하고 아래청정기는 시계방향으로 순환합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;1074&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qinc8/btsPZpH76Lg/EcDpKkzwFtKevac7ux78d1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qinc8/btsPZpH76Lg/EcDpKkzwFtKevac7ux78d1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qinc8/btsPZpH76Lg/EcDpKkzwFtKevac7ux78d1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqinc8%2FbtsPZpH76Lg%2FEcDpKkzwFtKevac7ux78d1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1278&quot; height=&quot;1074&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;1074&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공기청정기는 1초에 한칸씩 이동합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 1초가 지날때마다 위쪽 청정기의 위칸(2,1)에 있는 먼지가 사라지고, 아래쪽 청정기의 아래칸(5,1)에 있는 먼지가 사라집니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 구현하기 위한 아이디어는 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;T초간 반복문을 돌린다.&lt;/li&gt;
&lt;li&gt;먼지확산 함수를 돌린다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;주변에 //5만큼 확산시키고&lt;/li&gt;
&lt;li&gt;확산시킨만큼 미세먼지를 빼서 새로운 배열에 더해준다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;위쪽 공기청정기를 작동시킨다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;반시계 방향으로 미세먼지를 한칸씩 이동시킨다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;아래쪽 공기청정기를 작동시킨다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;시계 방향으로 미세먼지를 한칸씩 이동시킨다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 T만큼 반복문을 돌고 그 내부에서 3개의 함수가 돌아가기 때문에 시간복잡도는 다음과 같습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;T는 1000이고 바이러스 확산되는 횟수는 O(n^2) 50X50X4 하니 10000&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위쪽, 아래쪽 공기청정기 도는 횟수는 49 + 25 + 50 + 24 대략 300&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;10300 X 1000하면 10,300,000&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1000만회 돌기 때문에 1초의 2000만번 이하이기 때문에 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 구현&lt;/h2&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline

r, c, t = map(int, input().split())

rooms = []
air_conditioner = []
for i in range(r):
    data = list(map(int, input().split()))
    rooms.append(data)

    for j in range(c):
        if data[j] == -1:
            air_conditioner.append((i,j))
# 시계방향
dy = [0, 1, 0, -1]
dx = [1, 0, -1, 0]

# 반시계방향
top_dy = [0, -1, 0, 1]
top_dx = [1, 0, -1, 0]

# 먼지 확산 함수
def dust_spread(rooms):
    # 새로운 배열 준비
    new_rooms = [[0] * c for _ in range(r)]

    for y in range(r):
        for x in range(c):
            if rooms[y][x] &amp;gt; 0:
                spreaded_dust = 0
                for k in range(4):
                    ny = y + dy[k]
                    nx = x + dx[k]
                    
                    # 범위 내에 있거나 공기청정기가 아닐 때
                    if (0&amp;lt;=ny&amp;lt;r) and (0&amp;lt;=nx&amp;lt;c) and rooms[ny][nx] != -1:
                        spreaded_dust += (rooms[y][x] // 5) # 확산한 먼지 저장
                        new_rooms[ny][nx] += (rooms[y][x] // 5) # 주변 칸으로 확산
                
                # 원래 먼지 - 확산한 먼지로 업데이트
                new_rooms[y][x] += (rooms[y][x] - spreaded_dust)
    
    # 원래 공기청정기가 있었던 위치는 -1로 만들고
    for element in air_conditioner:
        ay, ax = element
        new_rooms[ay][ax] = -1
    
    # 확산한 방정보 리턴
    return new_rooms

# 위쪽 공기청정기 함수
def top_air_conditioner(depth, y, x, prev):
    # print(f&quot;현재 depth : {depth}, y : {y}, x : {x}, prev : {prev} 현재 값 : {rooms[y][x]}&quot;)
    ny = y + top_dy[depth]
    nx = x + top_dx[depth]
    
    # 범위 내에 있을 때
    if (0 &amp;lt;= ny &amp;lt; r) and (0 &amp;lt;= nx &amp;lt; c):
        # 공기청정기로 들어가면 함수 끝
        if rooms[ny][nx] == -1:
            rooms[y][x] = prev
            return
        
        # 먼지 다음칸으로 이동시키기
        next = rooms[y][x]
        rooms[y][x] = prev
        top_air_conditioner(depth, ny, nx, next)
    else: # 범위 밖으로 나갈 때
        # 반시계로 방향을 바꿔서 진행
        top_air_conditioner(depth + 1, y, x, prev)
        return  # 이 depth는 종료

# 아래쪽 공기청정기 함수(위쪽 공기청정기 함수에서 방향만 시계방향으로)
def bottom_air_conditioner(depth, y, x, prev):
    # print(f&quot;현재 depth : {depth}, y : {y}, x : {x}, prev : {prev} 현재 값 : {rooms[y][x]}&quot;)
    ny = y + dy[depth]
    nx = x + dx[depth]

    if (0 &amp;lt;= ny &amp;lt; r) and (0 &amp;lt;= nx &amp;lt; c):
        # 공기청정기로 들어가면 함수 끝
        if rooms[ny][nx] == -1:
            rooms[y][x] = prev
            return

        next = rooms[y][x]
        rooms[y][x] = prev

        bottom_air_conditioner(depth, ny, nx, next)
    else:
        bottom_air_conditioner(depth + 1, y, x, prev)
        return  # 이 depth는 종료

# 위 아래 공기 청정기 좌표 가져오기
top_y, top_x = air_conditioner[0]
bottom_y, bottom_x = air_conditioner[1]

# t만큼 반복문
for _ in range(t):
    rooms = dust_spread(rooms) # 먼지 확산
    top_air_conditioner(0, top_y, top_x+1, 0) # 위쪽 공기청정기 작동
    bottom_air_conditioner(0, bottom_y, bottom_x+1, 0) # 아래쪽 공기청정기 작동

# 배열의 모든 요소 더하기
answer = 0
for x in rooms:
    answer += sum(x)

# 모든 요소 더한것에서 공기청정기로 -2되어 결과 나온거 +2해서 출력
print(answer+2)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;느낀 점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 그래도 다른 블로그 참고하지 않고 스스로 풀어낸 문제라 뿌듯합니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 공기청정기로 시계방향, 반시계방향으로 먼지를 이동시키는 것을 구현하는 것이 꽤 힘들었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음 값을 저장하고 넘기는 것이 아직은 머리속으로 쉽게 그려지지 않아서 구현 문제를 더 많이 풀어보면서 재귀함수를 호출하는 것에 대해 익숙해져야겠다고 느꼈습니다.&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>구현</category>
      <category>백준 17144번</category>
      <category>백준 17144번 파이썬</category>
      <category>백준 미세먼지 안녕!</category>
      <author>기린성준</author>
      <guid isPermaLink="true">https://dev-sungjun.tistory.com/83</guid>
      <comments>https://dev-sungjun.tistory.com/83#entry83comment</comments>
      <pubDate>Tue, 19 Aug 2025 16:02:28 +0900</pubDate>
    </item>
  </channel>
</rss>