<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발새발</title>
    <link>https://zero0205.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 13 Jun 2026 09:06:15 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>딜레이레이</managingEditor>
    <image>
      <title>개발새발</title>
      <url>https://tistory1.daumcdn.net/tistory/4866232/attach/1e0d56da1d014efaa60c13cac2c3ba22</url>
      <link>https://zero0205.tistory.com</link>
    </image>
    <item>
      <title>[Javascript/자바스크립트] (프로그래머스) 후보키</title>
      <link>https://zero0205.tistory.com/992</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42890&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42890&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1749221105996&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(relation) {
  const answer = [];

  const dfs = (idx, picked) =&amp;gt; {
    if (idx === relation[0].length) {
      const result = relation.reduce((acc, cur) =&amp;gt; {
        acc.add(cur.filter((_, i) =&amp;gt; picked.has(i)).join(&quot;_&quot;));
        return acc;
      }, new Set());

      if (result.size === relation.length) {
        answer.push(new Set(picked));
      }
      return;
    }

    dfs(idx + 1, picked);
    picked.add(idx);
    dfs(idx + 1, picked);
    picked.delete(idx);
  };

  dfs(0, new Set());

  const remove_set = new Set();

  for (let i = 0; i &amp;lt; answer.length - 1; i++) {
    for (let j = i + 1; j &amp;lt; answer.length; j++) {
      const intersection = new Set(
        [...answer[i]].filter((x) =&amp;gt; answer[j].has(x))
      );

      if (intersection.size === answer[i].size) {
        remove_set.add(j);
      } else if (intersection.size === answer[j].size) {
        remove_set.add(i);
      }
    }
  }
  return answer.length - remove_set.size;
}&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;우선 DFS()를 활용하여 가능한 키의 조합을 모두 구한다. idx === n까지 돌아서 가능한 조합을 구했다면 해당 조합으로 후보키를 레코드를 유일하게 식별할 수 있는 조합(유일키)을 만들 수 있는지 알아본다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749221229750&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const result = relation.reduce((acc, cur) =&amp;gt; {
    acc.add(cur.filter((_, i) =&amp;gt; picked.has(i)).join(&quot;_&quot;));
    return acc;
}, new Set());

if (result.size === relation.length) {
	answer.push(new Set(picked));	
}&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;유일하게 식별할 수 있는 조합인지 판별하는 방법은 다음과 같다.&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;`picked`(선택된 컬럼들)의 값을 하나의 문자열로 묶은 값들의 집합을 구하고, 이 집합의 길이가 원본 배열의 길이와 같은지 확인하면 된다.&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;그리고 마지막으로는 위의 과정을 통해 모은 유일키들에서 최소성을 갖는 조합을 찾아내면 된다. 최소성 있는 조합을 가려내는 방법은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1749221482704&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (let i = 0; i &amp;lt; answer.length - 1; i++) {
    for (let j = i + 1; j &amp;lt; answer.length; j++) {
      const intersection = new Set(
        [...answer[i]].filter((x) =&amp;gt; answer[j].has(x))
      );

      if (intersection.size === answer[i].size) {
        remove_set.add(j);
      } else if (intersection.size === answer[j].size) {
        remove_set.add(i);
      }
    }
  }&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;한 조합이 다른 조합의 부분집합일 때, 더 큰 조합은 최소성을 갖지 않는 조합이므로 삭제 대상(remove_set)에 추가한다.&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;유일키들의 조합의 크기에서 최소성을 만족하지 않는 집합들의 크기를 빼면 바로 답이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>문제풀이/DFS_BFS</category>
      <category>dfs</category>
      <category>그래프탐색</category>
      <category>깊이우선탐색</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/992</guid>
      <comments>https://zero0205.tistory.com/992#entry992comment</comments>
      <pubDate>Fri, 6 Jun 2025 23:53:36 +0900</pubDate>
    </item>
    <item>
      <title>[Python/파이썬] 백준 1194번 달이 차오른다, 가자.</title>
      <link>https://zero0205.tistory.com/990</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1194&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/1194&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1749027787196&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from collections import deque

n, m = map(int, input().split())
maze = []
start = []
for i in range(n):
    line = list(input())
    for j in range(m):
        if line[j] == &quot;0&quot;:
            start = [i, j]
            line[j] = &quot;.&quot;
    maze.append(line)

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

q = deque([[*start, 0, frozenset()]])
visited = set()

while q:
    x, y, d, keys = q.popleft()

    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if 0 &amp;lt;= nx &amp;lt; n and 0 &amp;lt;= ny &amp;lt; m:
            new_keys = keys
            can_move = False
            if maze[nx][ny] == &quot;.&quot;:  # 빈 칸
                can_move = True
            elif maze[nx][ny].isalpha() and maze[nx][ny].islower():  # 열쇠 획득
                new_keys = keys | {maze[nx][ny]}
                can_move = True
            elif maze[nx][ny].isalpha() and maze[nx][ny].isupper() and maze[nx][ny].lower() in keys:    # 문 열고 이동
                can_move = True
            elif maze[nx][ny] == &quot;1&quot;:
                print(d+1)
                exit()

            if can_move and (nx, ny, new_keys) not in visited:
                q.append([nx, ny, d+1, new_keys])
                visited.add((nx, ny, new_keys))

print(-1)&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;모든 이동이 갖는 가중치가 같았기에 BFS를 사용해야 하는 문제였다. 다만, 주의해야 할 점은 일반적인 BFS와 다르게, 한 번 방문한 점이라도 키를 이전보다 더 갖고 오는 경우에는 다시 방문이 가능해야 한다는 점이다.&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;예를 들어, 1번째 테스트 케이스에서도 출발점에서 (0, 0)으로 가서 &quot;f&quot; 열쇠를 갖고 다시 출발점을 지나서 &quot;F&quot;문을 열고 지나가야 한다. 이런 경우들이 있을 수 있기 때문에 방문 처리를 할 때, 단순히 그 칸에 이전에 방문했는지 여부만 저장하면 안된다.&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;나는 방문 처리를 할 때, 칸 위치 정보와 더불어 가진 열쇠의 상태도 처리하도록 구현했다. 민식이가 소유한 열쇠 뭉치는 집합으로 표현했다. 이 때, 중간에 keys는 수정할 수 없는 집합인 `frozenset`에 넣어서 중간에 처리하며 값이 왜곡되는 것을 막았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;사실 민식이가 소유한 열쇠들을 집합이 아닌 비트마스킹을 이용해서 나타낼 수도 있다. &quot;a&quot;는 0번째 자리수, &quot;b&quot;는 1번째 자리수 이런식으로 말이다. 근데 이렇게 하려면 알파벳을 ASCII 코드로 변경해서 값을 계산하는 과정이 추가되어야 한다.&lt;/p&gt;</description>
      <category>문제풀이/DFS_BFS</category>
      <category>BFS</category>
      <category>그래프탐색</category>
      <category>너비우선탐색</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/990</guid>
      <comments>https://zero0205.tistory.com/990#entry990comment</comments>
      <pubDate>Wed, 4 Jun 2025 18:20:11 +0900</pubDate>
    </item>
    <item>
      <title>[Python/파이썬] 백준 11916번 볼질</title>
      <link>https://zero0205.tistory.com/989</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11916&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/11916&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1748961830516&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
base = [0]*4    # 0 ~ 2번째 원소는 각각 1루, 2루, 3루, 3번째 원소는 홈
ball_count = 0
answer = 0


def wild_pitch():
    global answer
    for i in range(2, -1, -1):
        if base[i] == 1:
            base[i+1] = 1
            base[i] = 0
    if base[3] == 1:
        answer += 1
        base[3] = 0


def ball_4():
    global answer
    if base[0] == 1:
        if base[1] == 1:
            if base[2] == 1:
                answer += 1
                base[2] = 0
            base[2] = 1
            base[1] = 0
        base[1] = 1
        base[0] = 0
    base[0] = 1


for b in map(int, input().split()):
    if b == 1:  # 볼
        ball_count += 1
    elif b == 2:    # 몸에 맞는 공
        ball_count = 4
    else:   # 폭투
        ball_count += 1
        wild_pitch()

    if ball_count &amp;gt;= 4:
        ball_4()
        ball_count = 0

print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설명&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `base`: 길이가 4인 1차원 배열이다. 각 원소는 순서대로 1루~3루, 그리고 홈을 뜻한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `ball_count`: 현재 타자의 볼 카운트이다.&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;그리고 이동은 2가지 종류가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 볼넷일 때의 이동(`ball_4()`)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 폭투로 인한 이동(`wild_pitch()`)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ball_4()&lt;/h4&gt;
&lt;pre id=&quot;code_1748962245554&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def ball_4():
    global answer
    if base[0] == 1:
        if base[1] == 1:
            if base[2] == 1:
                answer += 1
                base[2] = 0
            base[2] = 1
            base[1] = 0
        base[1] = 1
        base[0] = 0
    base[0] = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 자신을 포함해 앞의 주자들이 다 있어야만 진루할 수 있기 때문에 이런 중첩문의 구조를 갖게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 3루: 만루일 때 홈으로 들어가며 득점할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 2루: 1, 2루가 모두 있어야 2루 주자가 3루로 진루할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1루: 1루 주자가 있어야 2루로 진루할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 새로운 타자가 1루로 진출&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;wild_pitch()&lt;/h4&gt;
&lt;pre id=&quot;code_1748962336848&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def wild_pitch():
    global answer
    for i in range(2, -1, -1):
        if base[i] == 1:
            base[i+1] = 1
            base[i] = 0
    if base[3] == 1:
        answer += 1
        base[3] = 0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주자들이 무조건 진루를 하는 이동이기 때문에 크게 어려울 것은 없다. 다만, 앞쪽(1루 쪽)부터 진루 처리를 하면 뒷쪽의 데이터를 손상시킬 수 있기 때문에 3루부터 진루 처리를 해줘야 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 단순한 구현 문제인데, 생각이 한 번 꼬이면 빙빙 돌아갈 수도 있는 문제라서 정신 잘 붙잡고 풀어야 한다....&lt;/p&gt;</description>
      <category>문제풀이/구현</category>
      <category>Implementation</category>
      <category>구현</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/989</guid>
      <comments>https://zero0205.tistory.com/989#entry989comment</comments>
      <pubDate>Tue, 3 Jun 2025 23:54:16 +0900</pubDate>
    </item>
    <item>
      <title>[Python/파이썬] 백준 22953번 도도의 음식 준비</title>
      <link>https://zero0205.tistory.com/988</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/22953&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/22953&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1748842983484&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, k, c = map(int, input().split())
cooking_times = list(map(int, input().split()))

INF = int(1e12)
answer = INF


def total_cooking_time(arr, k):
    result = INF
    l, r = 1, INF
    while l &amp;lt;= r:
        mid = (l+r)//2

        count = 0
        for a in arr:
            count += mid//a
        if count &amp;lt; k:
            l = mid+1
        else:
            r = mid-1
            result = mid
    return result


def bt(idx, c):
    global answer
    if idx == n:
        answer = min(answer, total_cooking_time(cooking_times, k))
        return

    bt(idx+1, c)

    for encouragement in range(1, min(c+1, cooking_times[idx])):
        cooking_times[idx] -= encouragement
        bt(idx+1, c-encouragement)
        cooking_times[idx] += encouragement


cooking_times.sort()
start = 0
while start &amp;lt; n and cooking_times[start] == 1:
    start += 1
bt(start, c)
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;해당 문제를 풀기 위해서는 두 가지 알고리즘을 사용해야 했다.&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;- 백트래킹: 가능한 모든 격려 조합을 탐색하며 최적의 해를 찾는 데 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 파라메트릭 서치: k개 이상의 요리를 만들 수 있는 최소 시간을 찾는 데 사용&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;좀 더 자세하게 말해보자면 다음과 같은 과정으로 진행했다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;백트래킹&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 셰프에게 c번의 격려를 나눠서 주는 모든 조합을 구해서, 각 조합으로 요리를 했을 때 K개의 요리를 만드는데 얼마나 걸리는지 구한다. 이 과정을 통해 가장 최소 시간이 걸리는 경우를 구한다.&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;이때 조리시간이 1인 요리사는 격려할 수 없기 때문에 처음 호출하기 전에 1인 경우는 `bt()` 재귀호출 과정에 포함되지 않도록 했다.&lt;/p&gt;
&lt;pre id=&quot;code_1748845888520&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cooking_times.sort()
start = 0
while start &amp;lt; n and cooking_times[start] == 1:
    start += 1
bt(start, c)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;파라메트릭 서치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N명의 셰프들이 하나의 요리를 완성하는 데 걸리는 시간이 담긴 배열 `arr`와 완성해야 하는 요리의 총 개수 `k`를 인자로 받는다. 파라메트릭 서치를 이용하여 최소 몇 초 후에 k개 이상의 요리를 완성할 수 있는지를 구한다.&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;이때 주의해야 할 점이 2가지 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 탐색 범위: 문제에 제시된 조건 상 최악의 경우에 답의 범위는 10^12까지 가능하다. 평소에 이 정도 큰 범위는 자주 나오지 않기 때문에 문제의 조건을 보고 범위를 잘 설정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 조건: 정확히 K개의 요리를 완성하는 시간이 존재하지 않을 수도 있다. 그렇기 때문에 이분탐색처럼 정확히 K개의 요리를 완성하는 시점을 찾으면 안되고, K개 이상을 만들 수 있는 시점을 찾아야 한다.&lt;/p&gt;</description>
      <category>문제풀이/백트래킹</category>
      <category>backtracking</category>
      <category>binarySearch</category>
      <category>ParametricSearch</category>
      <category>백트래킹</category>
      <category>이분탐색</category>
      <category>파라메트릭서치</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/988</guid>
      <comments>https://zero0205.tistory.com/988#entry988comment</comments>
      <pubDate>Mon, 2 Jun 2025 15:37:56 +0900</pubDate>
    </item>
    <item>
      <title>[Python/파이썬] 백준 14627번 파닭파닭</title>
      <link>https://zero0205.tistory.com/987</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14627&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/14627&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1748787675986&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline

s, c = map(int, input().split())
green_onion = [int(input()) for _ in range(s)]

answer = 0
l, r = 1, max(green_onion)
while l &amp;lt;= r:
    mid = (l+r)//2

    chicken = 0
    ramyeon = 0
    for go in green_onion:
        chicken += go // mid
        ramyeon += go % mid

    if chicken &amp;gt;= c:
        l = mid+1
        answer = ramyeon + (chicken-c)*mid
    else:
        r = mid-1

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;이 문제는 조건을 만족하는 값 중 최대 값을 구하는 문제이기 때문에 파라메트릭 서치 알고리즘으로 풀 수 있는 문제이다. 여기서 조건은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 각 파닭에 같은 양의 파를 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;파라메트릭 서치에서는 조건을 만족하는지 확인하고, 만약 확인한다면 가능한 더 작은 범위로 좁혀서 탐색하는 것을 반복하며 최적의 해를 찾는다. 여기서는 다음의 코드로 조건을 만족하는지 확인한다. `mid`가 파닭에 들어가는 하나의 파의 길이이다.&lt;/p&gt;
&lt;pre id=&quot;code_1748787973708&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chicken = 0
ramyeon = 0
for go in green_onion:
    chicken += go // mid
    ramyeon += go % mid

if chicken &amp;gt;= c:
    l = mid+1
    answer = ramyeon + (chicken-c)*mid
else:
    r = mid-1&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;모든 파를 `mid` 길이로 썰었을 때, 주문받은 파닭 수(`c`) 이상 만들 수 있는지 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 만들 수 있다면 현재 c마리에 각각 `mid`만큼 넣어주고 남은 파를 `answer`에 저장하고, `l = mid+1`로 탐색 범위를 줄인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만들 수 없다면 r = mid-1로 각 파닭에 들어가는 파의 길이를 줄이는 쪽으로 탐색 범위를 줄인다.&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;이 과정을 `l`과 `r`이 같아질 때까지 반복하고 나서 `answer`의 값이 각 파닭에 조건을 만족하도록 파를 넣고 나서 남은 파의 길이, 즉 라면에 넣을 파의 길이이다.&lt;/p&gt;</description>
      <category>문제풀이/이분탐색</category>
      <category>binarySearch</category>
      <category>ParametricSearch</category>
      <category>이분탐색</category>
      <category>파라메트릭서치</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/987</guid>
      <comments>https://zero0205.tistory.com/987#entry987comment</comments>
      <pubDate>Sun, 1 Jun 2025 23:30:20 +0900</pubDate>
    </item>
    <item>
      <title>[Python/파이썬] 백준 17129번 윌리암슨수액빨이딱따구리가 정보섬에 올라온 이유</title>
      <link>https://zero0205.tistory.com/986</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17129&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/17129&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1748700155867&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
from collections import deque
input = sys.stdin.readline

n, m = map(int, input().split())
map_data = [input() for _ in range(n)]

for i in range(n):
    for j in range(m):
        if map_data[i][j] == &quot;2&quot;:
            start = [i, j]
            break

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

q = deque([[*start, 0]])
visited = [[False]*m for _ in range(n)]
visited[start[0]][start[1]] = True
while q:
    x, y, d = q.popleft()
    if map_data[x][y] in [&quot;3&quot;, &quot;4&quot;, &quot;5&quot;]:
        print(&quot;TAK\n{}&quot;.format(d))
        exit()
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if 0 &amp;lt;= nx &amp;lt; n and 0 &amp;lt;= ny &amp;lt; m and not visited[nx][ny] and map_data[nx][ny] != &quot;1&quot;:
            q.append([nx, ny, d+1])
            visited[nx][ny] = True
print(&quot;NIE&quot;)&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;격자 모양의 칸을 탐색해야 하는 문제이고, 각 칸을 이동하는데 걸리는 시간이 동일하기 때문에 BFS를 사용하여 풀었다. 윌리암어쩌구가 있는 곳(&quot;2&quot;)부터 &quot;3&quot; 또는 &quot;4&quot; 또는 &quot;5&quot; 중 하나가 나올 때까지 탐색하면 된다. 만약 갈 수 있는 모든 칸을 탐색하더라도 3, 4, 5 중 어느 것도 찾지 못한다면 &quot;NIE&quot;를 출력하면 된다.&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;N과 M의 범위가 워낙 커서 Python으로는 시간 초과가 발생하고, PyPy3로만 통과가 된다.&lt;/p&gt;</description>
      <category>문제풀이/DFS_BFS</category>
      <category>BFS</category>
      <category>그래프 탐색</category>
      <category>너비우선탐색</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/986</guid>
      <comments>https://zero0205.tistory.com/986#entry986comment</comments>
      <pubDate>Sat, 31 May 2025 23:03:45 +0900</pubDate>
    </item>
    <item>
      <title>[Python/파이썬] 백준 28422번 XOR 카드 게임</title>
      <link>https://zero0205.tistory.com/985</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/28422&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/28422&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1748618622685&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def xor_calculation(cards):
    result = cards[0]
    for i in range(1, len(cards)):
        result ^= cards[i]
    return bin(result).count(&quot;1&quot;)


n = int(input())
arr = [0]+list(map(int, input().split()))

if n == 1:
    print(0)
else:
    dp = [0]*(n+1)

    if n &amp;gt;= 2:
        dp[2] = xor_calculation(arr[1:3])
    if n &amp;gt;= 3:
        dp[3] = xor_calculation(arr[1:4])
    if n &amp;gt;= 4:
        dp[4] = dp[2] + xor_calculation(arr[3:5])
    for i in range(5, n+1):
        dp[i] = max(dp[i-2]+xor_calculation(arr[i-1:i+1]),
                    dp[i-3]+xor_calculation(arr[i-2:i+1]))
    print(dp[n])&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;카드가 4장뿐일 때를 고려를 못 해서 시간이 좀 걸렸다...:(&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>문제풀이/DP</category>
      <category>DP</category>
      <category>dynamicprogramming</category>
      <category>다이나믹프로그래밍</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/985</guid>
      <comments>https://zero0205.tistory.com/985#entry985comment</comments>
      <pubDate>Fri, 30 May 2025 23:59:04 +0900</pubDate>
    </item>
    <item>
      <title>[Python/파이썬] 백준 번 블로그2</title>
      <link>https://zero0205.tistory.com/984</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/20365&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/20365&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1748537688859&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
problems = input()

color_count = {'R': 0, 'B': 0}
color_count[problems[0]] += 1
for i in range(1, n):
    if problems[i] != problems[i-1]:
        color_count[problems[i]] += 1

print(min(color_count['R'], color_count['B'])+1)&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;같은 색이 연달아서 나오는 경우는 그냥 하나의 덩어리로 보면 된다. 그렇기에 가장 적은 횟수로 색칠하려면 더 색칠할 덩어리가 많은 경우를 하나의 색으로 칠해버리고 적은 덩어리를 따로따로 색칠한다고 생각하면 된다.&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;덩어리가 다른 색으로 바뀌는 경우를 세기 위해서 `color_count`라는 딕셔너리를 준비한다. 이때 처음 나오는 색도 처음으로 사용이 시작되는 부분이기 때문에 카운트해줘야 한다.&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;이렇게 빨간색이 모여있는 덩어리와 파란색이 모여있는 덩어리의 갯수를 센 뒤에 더 적은 덩어리의 갯수 + 1을 하면 정답이다. 이때, +1을 하는 경우는 더 많은 갯수의 덩어리를 가진 색으로 전체를 칠하는 횟수라고 생각하면 된다.&lt;/p&gt;</description>
      <category>문제풀이</category>
      <category>greedy</category>
      <category>그리디</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/984</guid>
      <comments>https://zero0205.tistory.com/984#entry984comment</comments>
      <pubDate>Thu, 29 May 2025 23:57:11 +0900</pubDate>
    </item>
    <item>
      <title>[Javascript/자바스크립트] 백준 14938번 서강그라운드</title>
      <link>https://zero0205.tistory.com/983</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14938&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/14938&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1748337303923&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const fs = require(&quot;fs&quot;);
const filePath = process.platform === &quot;linux&quot; ? &quot;dev/stdin&quot; : &quot;./input.txt&quot;;
const input = fs.readFileSync(filePath).toString().trim().split(&quot;\n&quot;);

const [n, m, r] = input[0]
  .trim()
  .split(&quot; &quot;)
  .map((val) =&amp;gt; +val);
const itemCount = input[1]
  .trim()
  .split(&quot; &quot;)
  .map((val) =&amp;gt; +val);
const roads = input.slice(2).map((val) =&amp;gt;
  val
    .trim()
    .split(&quot; &quot;)
    .map((val) =&amp;gt; +val)
);

function solution2(n, m, r, itemCount, roads) {
  const distance = Array.from(new Array(n + 1), () =&amp;gt;
    new Array(n + 1).fill(Number.MAX_SAFE_INTEGER)
  );

  for (let i = 0; i &amp;lt;= n; i++) {
    distance[i][i] = 0;
  }

  for (const [a, b, l] of roads) {
    distance[a][b] = l;
    distance[b][a] = l;
  }

  for (let k = 1; k &amp;lt;= n; k++) {
    for (let i = 1; i &amp;lt;= n; i++) {
      for (let j = 1; j &amp;lt;= n; j++) {
        if (distance[i][j] &amp;gt; distance[i][k] + distance[k][j]) {
          distance[i][j] = distance[i][k] + distance[k][j];
        }
      }
    }
  }

  let answer = 0;
  for (let i = 1; i &amp;lt;= n; i++) {
    let itemsSum = 0;
    for (let j = 1; j &amp;lt;= n; j++) {
      if (distance[i][j] &amp;lt;= m) {
        itemsSum += itemCount[j - 1];
      }
    }
    answer = Math.max(answer, itemsSum);
  }

  return answer;
}

console.log(solution2(n, m, r, itemCount, roads));&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;</description>
      <category>문제풀이/최단경로</category>
      <category>Floyd-Warshall</category>
      <category>최단거리</category>
      <category>최단경로</category>
      <category>플로이드워셜</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/983</guid>
      <comments>https://zero0205.tistory.com/983#entry983comment</comments>
      <pubDate>Tue, 27 May 2025 18:17:12 +0900</pubDate>
    </item>
    <item>
      <title>[Javascript/자바스크립트] (프로그래머스) 미로 탈출</title>
      <link>https://zero0205.tistory.com/982</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/159993&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/159993&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1748266563266&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const bfs = (maps, start, end) =&amp;gt; {
  const n = maps.length;
  const m = maps[0].length;

  const dx = [-1, 1, 0, 0];
  const dy = [0, 0, -1, 1];
  const q = [[...start, 0]];
  const visited = Array.from(new Array(n), () =&amp;gt; new Array(m).fill(false));
  visited[start[0]][start[1]] = true;
  while (q.length &amp;gt; 0) {
    const [x, y, d] = q.shift();
    if (x === end[0] &amp;amp;&amp;amp; y === end[1]) return d;
    for (let i = 0; i &amp;lt; 4; i++) {
      const nx = x + dx[i];
      const ny = y + dy[i];
      if (nx &amp;lt; 0 || nx &amp;gt;= n || ny &amp;lt; 0 || ny &amp;gt;= m) continue;
      if (!visited[nx][ny] &amp;amp;&amp;amp; maps[nx][ny] !== &quot;X&quot;) {
        q.push([nx, ny, d + 1]);
        visited[nx][ny] = true;
      }
    }
  }
  return -1;
};

function solution(maps) {
  let start = undefined;
  let end = undefined;
  let lever = undefined;
  for (let i = 0; i &amp;lt; maps.length; i++) {
    for (let j = 0; j &amp;lt; maps[0].length; j++) {
      if (maps[i][j] === &quot;S&quot;) start = [i, j];
      if (maps[i][j] === &quot;E&quot;) end = [i, j];
      if (maps[i][j] === &quot;L&quot;) lever = [i, j];
    }
  }

  // 시작점-레버 최단거리 구하기
  const startToLeverDistance = bfs(maps, start, lever);
  if (startToLeverDistance === -1) return -1;
  // 레버-도착점 최단거리 구하기
  const leverToEndDistance = bfs(maps, lever, end);

  return leverToEndDistance === -1
    ? -1
    : startToLeverDistance + leverToEndDistance;
}&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;출발점부터 레버까지의 거리를 구하고 나서, 레버부터 도착점까지의 거리를 구하면 되는 쉬운 문제였다.&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;두 점의 최단거리를 구할때는 모든 칸에서 다음 칸으로 이동하는데 소요되는 시간이 같으므로 이런 상황에 최적의 해를 찾을 수 있는 알고리즘인 BFS를 사용한다.&lt;/p&gt;</description>
      <category>문제풀이/DFS_BFS</category>
      <category>BFS</category>
      <category>그래프탐색</category>
      <category>너비우선탐색</category>
      <author>딜레이레이</author>
      <guid isPermaLink="true">https://zero0205.tistory.com/982</guid>
      <comments>https://zero0205.tistory.com/982#entry982comment</comments>
      <pubDate>Mon, 26 May 2025 22:43:01 +0900</pubDate>
    </item>
  </channel>
</rss>