<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://munjjang9.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://munjjang9.github.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-03-16T01:28:53+00:00</updated><id>https://munjjang9.github.io/feed.xml</id><title type="html">문짱구의 게임 개발 블로그</title><subtitle>Game Programmer</subtitle><author><name>munjjang9</name><email>munzzang9@gmail.com</email></author><entry><title type="html">[프로그래머스] 타겟 넘버 (Lv.2)</title><link href="https://munjjang9.github.io/codingtest/2026/03/14/PS-%ED%83%80%EA%B2%9F%EB%84%98%EB%B2%84/" rel="alternate" type="text/html" title="[프로그래머스] 타겟 넘버 (Lv.2)" /><published>2026-03-14T14:00:00+00:00</published><updated>2026-03-14T14:00:00+00:00</updated><id>https://munjjang9.github.io/codingtest/2026/03/14/PS-%ED%83%80%EA%B2%9F%EB%84%98%EB%B2%84</id><content type="html" xml:base="https://munjjang9.github.io/codingtest/2026/03/14/PS-%ED%83%80%EA%B2%9F%EB%84%98%EB%B2%84/"><![CDATA[<h2 id="문제-링크">문제 링크</h2>
<hr />
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/43165">프로그래머스 - 타겟 넘버</a></p>

<p><br /></p>

<h2 id="문제-설명">문제 설명</h2>
<hr />
<p>n개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다.</p>

<p>예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
</code></pre></div></div>

<p>사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.</p>

<p><strong>제한사항</strong></p>
<ul>
  <li>주어지는 숫자의 개수는 2개 이상 20개 이하입니다.</li>
  <li>각 숫자는 1 이상 50 이하인 자연수입니다.</li>
  <li>타겟 넘버는 1 이상 1000 이하인 자연수입니다.</li>
</ul>

<p><br /></p>

<h2 id="내-풀이">내 풀이</h2>
<hr />
<p>각 숫자마다 더하거나 빼는 두 가지 선택지가 있으므로, 재귀 DFS로 모든 경우를 탐색했다.</p>

<p><code class="language-plaintext highlighter-rouge">dfs(idx, current)</code>는 <code class="language-plaintext highlighter-rouge">idx</code>번째 숫자를 선택할 차례이고, 지금까지의 합이 <code class="language-plaintext highlighter-rouge">current</code>인 상태를 의미한다. 숫자를 더하는 방향과 빼는 방향으로 각각 재귀 호출해 트리 전체를 탐색하고, 마지막 숫자까지 선택했을 때 합이 <code class="language-plaintext highlighter-rouge">target</code>이면 카운트를 1 증가시킨다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="kt">int</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">Numbers</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">Target</span><span class="p">;</span>

<span class="kt">void</span> <span class="nf">dfs</span><span class="p">(</span><span class="kt">int</span> <span class="n">idx</span><span class="p">,</span> <span class="kt">int</span> <span class="n">current</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span><span class="p">(</span><span class="n">idx</span> <span class="o">==</span> <span class="n">Numbers</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
    <span class="p">{</span>
        <span class="k">if</span><span class="p">(</span><span class="n">current</span> <span class="o">==</span> <span class="n">Target</span><span class="p">)</span> <span class="n">count</span><span class="o">++</span><span class="p">;</span>
        <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="n">dfs</span><span class="p">(</span><span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">current</span> <span class="o">+</span> <span class="n">Numbers</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>
    <span class="n">dfs</span><span class="p">(</span><span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">current</span> <span class="o">-</span> <span class="n">Numbers</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="n">solution</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">numbers</span><span class="p">,</span> <span class="kt">int</span> <span class="n">target</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="n">Numbers</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">;</span>
    <span class="n">Target</span> <span class="o">=</span> <span class="n">target</span><span class="p">;</span>
    
    <span class="n">dfs</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
    
    
    <span class="k">return</span> <span class="n">count</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<h2 id="시간복잡도-분석">시간복잡도 분석</h2>
<hr />
<p>각 숫자마다 + / - 두 가지 선택을 하므로, 숫자가 n개일 때 총 경우의 수는 2^n이다.</p>

<table>
  <thead>
    <tr>
      <th>단계</th>
      <th>시간복잡도</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>DFS 전체 탐색</td>
      <td>O(2^N)</td>
    </tr>
  </tbody>
</table>

<p>제한사항에서 N ≤ 20이므로 2^20 = 약 <strong>100만 연산</strong>으로 충분히 통과 가능하다.</p>

<p><br /></p>

<h2 id="오답노트">오답노트</h2>
<hr />
<p><strong>오류: Segmentation Fault</strong></p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 수정 전</span>
<span class="n">dfs</span><span class="p">(</span><span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">current</span> <span class="o">+</span> <span class="n">Numbers</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>
<span class="n">dfs</span><span class="p">(</span><span class="n">idx</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">current</span> <span class="o">-</span> <span class="n">Numbers</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>  <span class="c1">// ← idx - 1이 잘못됨</span>

<span class="c1">// 수정 후</span>
<span class="n">dfs</span><span class="p">(</span><span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">current</span> <span class="o">+</span> <span class="n">Numbers</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>
<span class="n">dfs</span><span class="p">(</span><span class="n">idx</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">current</span> <span class="o">-</span> <span class="n">Numbers</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>  <span class="c1">// 방향(+/-)과 인덱스 이동은 별개</span>
</code></pre></div></div>

<p>빼는 방향(-) 선택이어도 <strong>다음 숫자로 이동</strong>해야 한다. <code class="language-plaintext highlighter-rouge">idx - 1</code>로 작성하면 인덱스가 음수로 내려가며 무한 재귀 → 스택 오버플로우가 발생한다.</p>

<p><br /></p>

<h2 id="후기">후기</h2>
<hr />
<p>문제를 이해하는 건 어렵지 않았지만, 처음에 코드로 옮기는 작업이 조금 어려웠다. 이런 문제들을 좀 많이 풀면서, 생각한 로직을 코드로 옮기는 것에 익숙해져야겠다.</p>]]></content><author><name>munjjang9</name></author><category term="CodingTest" /><category term="Algorithm" /><category term="CodingTest" /><category term="DFS" /><summary type="html"><![CDATA[문제 링크 프로그래머스 - 타겟 넘버]]></summary></entry><entry><title type="html">[프로그래머스] 게임 맵 최단거리 (Lv.2)</title><link href="https://munjjang9.github.io/codingtest/2026/03/14/PS-%EA%B2%8C%EC%9E%84%EB%A7%B5%EC%B5%9C%EB%8B%A8%EA%B1%B0%EB%A6%AC/" rel="alternate" type="text/html" title="[프로그래머스] 게임 맵 최단거리 (Lv.2)" /><published>2026-03-14T13:05:00+00:00</published><updated>2026-03-14T13:05:00+00:00</updated><id>https://munjjang9.github.io/codingtest/2026/03/14/PS-%EA%B2%8C%EC%9E%84%EB%A7%B5%EC%B5%9C%EB%8B%A8%EA%B1%B0%EB%A6%AC</id><content type="html" xml:base="https://munjjang9.github.io/codingtest/2026/03/14/PS-%EA%B2%8C%EC%9E%84%EB%A7%B5%EC%B5%9C%EB%8B%A8%EA%B1%B0%EB%A6%AC/"><![CDATA[<h2 id="문제-링크">문제 링크</h2>
<hr />
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/1844">프로그래머스 - 게임 맵 최단거리</a></p>

<p><br /></p>

<h2 id="문제-설명">문제 설명</h2>
<hr />
<p>ROR 게임에서 당신은 상대 팀 진영을 공격하기 위해 지금 제일 빠른 길을 찾아야 합니다.</p>

<p>지도는 n×m 크기의 2차원 배열입니다. 0은 벽으로 막힌 공간, 1은 이동할 수 있는 공간입니다. 캐릭터는 좌, 우, 위, 아래 네 방향으로만 이동할 수 있습니다.</p>

<p>캐릭터가 처음 놓인 칸 (1, 1)에서 상대 팀 진영인 (n, m)까지 최단거리로 이동하면 몇 칸을 지나야 하는지 구해주세요. 이동할 수 없는 경우 -1을 반환합니다.</p>

<p><strong>제한사항</strong></p>
<ul>
  <li>maps는 n × m 크기의 게임 맵의 상태가 들어있는 2차원 배열로, n과 m은 각각 1 이상 100 이하의 자연수입니다.</li>
  <li>n과 m은 서로 같을 수도, 다를 수도 있지만, n과 m이 모두 1인 경우는 입력으로 주어지지 않습니다.</li>
  <li>maps는 0과 1로만 이루어져 있으며, 0은 벽이 있는 자리, 1은 벽이 없는 자리를 나타냅니다.</li>
  <li>처음에 캐릭터는 게임 맵의 좌측 상단인 (1, 1) 위치에 있으며, 상대방 진영은 게임 맵의 우측 하단인 (n, m) 위치에 있습니다.</li>
</ul>

<p><br /></p>

<h2 id="내-풀이">내 풀이</h2>
<hr />
<p>2D 격자를 그래프로 보고 BFS로 최단거리를 탐색했다.</p>

<p><code class="language-plaintext highlighter-rouge">dist</code> 배열을 -1로 초기화해 미방문 표시와 visited 역할을 겸하게 했다. 시작점 (0, 0)에서 출발해 상하좌우 4방향으로 이동하며, 이동할 때마다 <code class="language-plaintext highlighter-rouge">dist[nx][ny] = dist[x][y] + 1</code>로 거리를 누적한다. 목적지 (N-1, M-1)에 도달하면 <code class="language-plaintext highlighter-rouge">dist[x][y] + 1</code>을 반환하고, 큐가 빌 때까지 도달하지 못하면 -1을 반환한다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;queue&gt;</span><span class="cp">
</span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="kt">int</span> <span class="n">N</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">M</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">Maps</span><span class="p">;</span>

<span class="kt">int</span> <span class="n">Dx</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span>  <span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">Dy</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>  <span class="mi">0</span><span class="p">,</span>  <span class="mi">0</span><span class="p">};</span>

<span class="kt">int</span> <span class="n">bfs</span><span class="p">(</span><span class="kt">int</span> <span class="n">start_x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">start_y</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">queue</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">q</span><span class="p">;</span>
    <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">dist</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">M</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">));</span>
    
    <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">start_x</span><span class="p">,</span> <span class="n">start_y</span><span class="p">});</span>
    <span class="n">dist</span><span class="p">[</span><span class="n">start_x</span><span class="p">][</span><span class="n">start_y</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    
    <span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
    <span class="p">{</span>
        <span class="k">auto</span> <span class="p">[</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
        <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
        
        <span class="k">if</span><span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="n">N</span><span class="o">-</span><span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">==</span> <span class="n">M</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="n">dist</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
        
        <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">d</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">d</span> <span class="o">&lt;</span> <span class="mi">4</span><span class="p">;</span> <span class="n">d</span><span class="o">++</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="kt">int</span> <span class="n">nx</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">Dx</span><span class="p">[</span><span class="n">d</span><span class="p">];</span>
            <span class="kt">int</span> <span class="n">ny</span> <span class="o">=</span> <span class="n">y</span> <span class="o">+</span> <span class="n">Dy</span><span class="p">[</span><span class="n">d</span><span class="p">];</span>
            
            <span class="k">if</span><span class="p">(</span><span class="n">nx</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">nx</span> <span class="o">&gt;=</span> <span class="n">N</span> <span class="o">||</span> <span class="n">ny</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">ny</span> <span class="o">&gt;=</span> <span class="n">M</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
            
            <span class="k">if</span><span class="p">(</span><span class="n">Maps</span><span class="p">[</span><span class="n">nx</span><span class="p">][</span><span class="n">ny</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
            <span class="k">if</span><span class="p">(</span><span class="n">dist</span><span class="p">[</span><span class="n">nx</span><span class="p">][</span><span class="n">ny</span><span class="p">]</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
            
            <span class="n">dist</span><span class="p">[</span><span class="n">nx</span><span class="p">][</span><span class="n">ny</span><span class="p">]</span> <span class="o">=</span> <span class="n">dist</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
            <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">nx</span><span class="p">,</span> <span class="n">ny</span><span class="p">});</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>


<span class="kt">int</span> <span class="n">solution</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&gt;</span> <span class="n">maps</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">Maps</span> <span class="o">=</span> <span class="n">maps</span><span class="p">;</span>
    <span class="n">N</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">maps</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
    <span class="n">M</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">maps</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">();</span>
    
    <span class="k">return</span> <span class="n">bfs</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<h2 id="시간복잡도-분석">시간복잡도 분석</h2>
<hr />
<p>N×M 격자의 모든 칸을 최대 한 번씩만 방문하므로 전체 시간복잡도는 O(N × M)이다.</p>

<table>
  <thead>
    <tr>
      <th>단계</th>
      <th>시간복잡도</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>BFS 전체 탐색</td>
      <td>O(N × M)</td>
    </tr>
  </tbody>
</table>

<p>제한사항에서 N, M ≤ 100이므로 최대 <strong>10,000 연산</strong>으로 충분히 통과 가능하다.</p>

<p><br /></p>

<h2 id="오답노트">오답노트</h2>
<hr />
<p><strong>오류: 이동 횟수와 칸의 수 혼동</strong></p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 수정 전</span>
<span class="k">if</span><span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="n">N</span><span class="o">-</span><span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">==</span> <span class="n">M</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="n">dist</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">];</span>    <span class="c1">// 이동 횟수(엣지 수) 반환</span>

<span class="c1">// 수정 후</span>
<span class="k">if</span><span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="n">N</span><span class="o">-</span><span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">==</span> <span class="n">M</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="n">dist</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 칸의 수(노드 수) 반환</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">dist[0][0] = 0</code>으로 시작하면 목적지의 dist 값은 이동 횟수(엣지 수)다.
문제가 요구하는 건 <strong>“몇 칸을 지나야 하는지”</strong> — 시작 칸을 포함한 칸의 수(노드 수)이므로 +1이 필요하다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(0,0) → (1,0) → ... → (N-1,M-1)
dist:  0      1           10      → 반환값: 10 + 1 = 11칸
</code></pre></div></div>

<p><br /></p>

<h2 id="후기">후기</h2>
<hr />
<p>이 문제도 어떻게 풀어야 하는지를 잘 몰라서 처음에 많이 헤매다가 공부를 다시 하고 풀어봤다. 이렇게 푸는거구나 라는 흐름을 익히고 나중에 한 번 더 도전해보는 것도 좋을 것 같다.</p>]]></content><author><name>munjjang9</name></author><category term="CodingTest" /><category term="Algorithm" /><category term="CodingTest" /><category term="BFS" /><summary type="html"><![CDATA[문제 링크 프로그래머스 - 게임 맵 최단거리]]></summary></entry><entry><title type="html">DFS / BFS</title><link href="https://munjjang9.github.io/algorithm/2026/03/14/DFSBFS/" rel="alternate" type="text/html" title="DFS / BFS" /><published>2026-03-14T12:00:00+00:00</published><updated>2026-03-14T12:00:00+00:00</updated><id>https://munjjang9.github.io/algorithm/2026/03/14/DFSBFS</id><content type="html" xml:base="https://munjjang9.github.io/algorithm/2026/03/14/DFSBFS/"><![CDATA[<h2 id="전날-내용-요약--탐욕법-greedy">전날 내용 요약 — 탐욕법 (Greedy)</h2>

<ul>
  <li>탐욕법 = 매 순간 현재 시점에서 가장 좋은 선택만 하는 전략</li>
  <li>적용 조건 두 가지: <strong>탐욕 선택 속성</strong> (현재 최선이 미래 최선을 보장) + <strong>최적 부분 구조</strong> (부분 최적이 모여 전체 최적)</li>
  <li>반례가 하나라도 있으면 탐욕 불가 → DP로 전환</li>
  <li>패턴 1 — 정렬 후 앞에서 순서대로 선택 (과자 나눠주기)</li>
  <li>패턴 2 — 정렬 후 양끝 포인터로 최적 쌍 선택 (구명보트/짐 싣기)</li>
  <li>시간복잡도: 정렬이 병목 → 전체 O(N log N)</li>
</ul>

<hr />

<h2 id="dfs--bfs란">DFS / BFS란?</h2>

<p>지금까지 배운 정렬, 해시, 완전탐색, 탐욕은 주로 1차원 배열에서 동작했다.
하지만 게임에서는 미로 경로 찾기, 연결된 구역 세기, 최단 이동 거리 계산 같은 문제들이 자주 등장한다.
이런 문제들은 <strong>그래프</strong> 형태로 모델링되고, 이를 탐색하는 두 가지 핵심 방법이 DFS와 BFS다.</p>

<ul>
  <li><strong>DFS (Depth-First Search)</strong>: 한 방향으로 갈 수 있는 한 최대한 깊이 들어가고, 더 이상 못 가면 돌아와서 다른 방향 탐색</li>
  <li><strong>BFS (Breadth-First Search)</strong>: 가장 가까운 노드부터 먼저 탐색, 거리(레벨) 순서대로 퍼져나감</li>
</ul>

<hr />

<h2 id="그래프-표현-방법">그래프 표현 방법</h2>

<p>그래프는 <strong>노드(정점)</strong>와 <strong>간선(연결)</strong>으로 구성된다.
코딩테스트에서는 주로 <strong>인접 리스트</strong>를 사용한다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span> <span class="c1">// 노드 수</span>
<span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">adj</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>

<span class="c1">// 0-1, 0-2, 1-3, 1-4 연결</span>
<span class="n">adj</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">};</span>
<span class="n">adj</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">};</span>
<span class="n">adj</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">adj</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">};</span>
<span class="n">adj</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">};</span>
</code></pre></div></div>

<p>인접 행렬은 O(N²) 공간을 사용하므로 N이 작을 때 (≤ 1,000) 쓰고,
인접 리스트는 O(N + E) 공간으로 N이 클 때 (≤ 100,000) 적합하다.
코테에서는 대부분 인접 리스트를 쓴다.</p>

<hr />

<h2 id="dfs-깊이-우선-탐색">DFS (깊이 우선 탐색)</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0 방문 → 1 방문 → 3 방문 → 막힘 → 되돌아와 4 방문 → 막힘 → 되돌아와 → 2 방문
</code></pre></div></div>

<p>재귀로 구현하는 게 가장 자연스럽다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">adj</span><span class="p">;</span>
<span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">visited</span><span class="p">;</span>

<span class="kt">void</span> <span class="nf">dfs</span><span class="p">(</span><span class="kt">int</span> <span class="n">node</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">visited</span><span class="p">[</span><span class="n">node</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">node</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">next</span> <span class="o">:</span> <span class="n">adj</span><span class="p">[</span><span class="n">node</span><span class="p">])</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">visited</span><span class="p">[</span><span class="n">next</span><span class="p">])</span>
            <span class="n">dfs</span><span class="p">(</span><span class="n">next</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// 사용</span>
<span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">adj</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
<span class="n">visited</span><span class="p">.</span><span class="n">assign</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
<span class="c1">// ... 간선 추가 ...</span>
<span class="n">dfs</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="c1">// 0 1 3 4 2</span>
</code></pre></div></div>

<p>visited 배열 없이 탐색하면 0→1→0→1→… 무한루프에 빠진다.
이미 간 곳은 다시 가지 않는다는 표시가 필수다.</p>

<hr />

<h2 id="bfs-너비-우선-탐색">BFS (너비 우선 탐색)</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0 방문 → 1, 2 방문 (거리 1) → 3, 4 방문 (거리 2)
</code></pre></div></div>

<p>BFS는 반드시 큐로 구현한다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">bfs</span><span class="p">(</span><span class="kt">int</span> <span class="n">start</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">queue</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">q</span><span class="p">;</span>
    <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">start</span><span class="p">);</span>
    <span class="n">visited</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>

    <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
        <span class="kt">int</span> <span class="n">node</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span> <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">node</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span>

        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">next</span> <span class="o">:</span> <span class="n">adj</span><span class="p">[</span><span class="n">node</span><span class="p">])</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">visited</span><span class="p">[</span><span class="n">next</span><span class="p">])</span> <span class="p">{</span>
                <span class="n">visited</span><span class="p">[</span><span class="n">next</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
                <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">next</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// 0 1 2 3 4</span>
</code></pre></div></div>

<p>visited 체크를 pop할 때 하면 같은 노드가 큐에 여러 번 들어갈 수 있다.
<strong>push할 때 즉시 visited = true</strong>로 설정하는 게 올바른 패턴이다.</p>

<hr />

<h2 id="최단-거리--bfs-활용">최단 거리 — BFS 활용</h2>

<p>BFS는 <strong>가중치 없는 그래프에서 최단 거리를 보장</strong>한다.
레벨 순서로 탐색하기 때문에, 처음 도달했을 때가 항상 최단 거리다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">dist</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// -1 = 미방문</span>

<span class="kt">void</span> <span class="nf">bfs_dist</span><span class="p">(</span><span class="kt">int</span> <span class="n">start</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">queue</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">q</span><span class="p">;</span>
    <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">start</span><span class="p">);</span>
    <span class="n">dist</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
        <span class="kt">int</span> <span class="n">node</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span> <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>

        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">next</span> <span class="o">:</span> <span class="n">adj</span><span class="p">[</span><span class="n">node</span><span class="p">])</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">dist</span><span class="p">[</span><span class="n">next</span><span class="p">]</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">dist</span><span class="p">[</span><span class="n">next</span><span class="p">]</span> <span class="o">=</span> <span class="n">dist</span><span class="p">[</span><span class="n">node</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 거리 1씩 증가</span>
                <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">next</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>dist 배열이 -1이면 미방문이므로, visited 배열을 따로 쓰지 않아도 된다.</p>

<hr />

<h2 id="2d-격자-탐색-패턴">2D 격자 탐색 패턴</h2>

<p>맵 문제(미로, 섬 세기 등)는 2D 배열을 그래프처럼 탐색한다.
상하좌우 4방향 이동이 “인접 노드” 역할을 한다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">n</span><span class="p">,</span> <span class="n">m</span><span class="p">;</span> <span class="c1">// 행, 열</span>
<span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">grid</span><span class="p">;</span>

<span class="kt">int</span> <span class="n">dx</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">};</span> <span class="c1">// 상하좌우 x 변화량</span>
<span class="kt">int</span> <span class="n">dy</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span> <span class="c1">// 상하좌우 y 변화량</span>

<span class="c1">// BFS로 (sx, sy)에서 출발해 (ex, ey)까지 최단 거리</span>
<span class="kt">int</span> <span class="n">bfs_grid</span><span class="p">(</span><span class="kt">int</span> <span class="n">sx</span><span class="p">,</span> <span class="kt">int</span> <span class="n">sy</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ex</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ey</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">queue</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">q</span><span class="p">;</span>
    <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">dist</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">));</span>

    <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">sx</span><span class="p">,</span> <span class="n">sy</span><span class="p">});</span>
    <span class="n">dist</span><span class="p">[</span><span class="n">sx</span><span class="p">][</span><span class="n">sy</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">auto</span> <span class="p">[</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span> <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>

        <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="n">ex</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">==</span> <span class="n">ey</span><span class="p">)</span> <span class="k">return</span> <span class="n">dist</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">];</span>

        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">d</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">d</span> <span class="o">&lt;</span> <span class="mi">4</span><span class="p">;</span> <span class="n">d</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="kt">int</span> <span class="n">nx</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">dx</span><span class="p">[</span><span class="n">d</span><span class="p">];</span>
            <span class="kt">int</span> <span class="n">ny</span> <span class="o">=</span> <span class="n">y</span> <span class="o">+</span> <span class="n">dy</span><span class="p">[</span><span class="n">d</span><span class="p">];</span>

            <span class="c1">// 범위 체크 + 벽 체크 + 미방문 체크</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">nx</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">nx</span> <span class="o">&gt;=</span> <span class="n">n</span> <span class="o">||</span> <span class="n">ny</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">ny</span> <span class="o">&gt;=</span> <span class="n">m</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="n">nx</span><span class="p">][</span><span class="n">ny</span><span class="p">]</span> <span class="o">==</span> <span class="sc">'1'</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span> <span class="c1">// '1'이 벽</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">dist</span><span class="p">[</span><span class="n">nx</span><span class="p">][</span><span class="n">ny</span><span class="p">]</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>

            <span class="n">dist</span><span class="p">[</span><span class="n">nx</span><span class="p">][</span><span class="n">ny</span><span class="p">]</span> <span class="o">=</span> <span class="n">dist</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
            <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">({</span><span class="n">nx</span><span class="p">,</span> <span class="n">ny</span><span class="p">});</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="c1">// 도달 불가</span>
<span class="p">}</span>
</code></pre></div></div>

<p>dx/dy 배열 패턴은 2D 탐색 문제에서 거의 매번 등장한다. 외워두는 게 좋다.</p>

<hr />

<h2 id="dfs-vs-bfs-비교">DFS vs BFS 비교</h2>

<table>
  <thead>
    <tr>
      <th>기준</th>
      <th>DFS</th>
      <th>BFS</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>구현 방식</td>
      <td>재귀 or 스택</td>
      <td>큐</td>
    </tr>
    <tr>
      <td>탐색 순서</td>
      <td>깊이 우선</td>
      <td>거리(레벨) 순</td>
    </tr>
    <tr>
      <td>최단 거리 보장</td>
      <td>❌</td>
      <td>✅ (가중치 없을 때)</td>
    </tr>
    <tr>
      <td>모든 경우 탐색</td>
      <td>✅</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>주요 활용</td>
      <td>연결 요소 세기, 경로 존재 여부, 조합 탐색</td>
      <td>최단 거리, 최소 이동 횟수</td>
    </tr>
  </tbody>
</table>

<p><strong>판단 기준</strong></p>
<ul>
  <li>“최단 거리/최소 횟수”가 나오면 → <strong>BFS</strong></li>
  <li>“경로 존재 여부”, “연결된 영역 세기” → <strong>DFS or BFS 모두 가능</strong></li>
  <li>“모든 경우 탐색” (완전탐색과 혼합) → <strong>DFS</strong></li>
</ul>

<hr />

<h2 id="시간복잡도">시간복잡도</h2>

<p>DFS와 BFS 모두 모든 노드와 간선을 한 번씩 방문하므로 시간복잡도는 동일하다.</p>

<table>
  <thead>
    <tr>
      <th>구분</th>
      <th>시간복잡도</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>DFS</td>
      <td>O(V + E)</td>
    </tr>
    <tr>
      <td>BFS</td>
      <td>O(V + E)</td>
    </tr>
    <tr>
      <td>2D 격자 (N×M)</td>
      <td>O(N × M)</td>
    </tr>
  </tbody>
</table>]]></content><author><name>munjjang9</name></author><category term="Algorithm" /><category term="Algorithm" /><category term="DFS" /><category term="BFS" /><category term="C++" /><summary type="html"><![CDATA[전날 내용 요약 — 탐욕법 (Greedy)]]></summary></entry><entry><title type="html">[프로그래머스] 구명보트 (Lv.2)</title><link href="https://munjjang9.github.io/codingtest/2026/03/13/PS-%EA%B5%AC%EB%AA%85%EB%B3%B4%ED%8A%B8/" rel="alternate" type="text/html" title="[프로그래머스] 구명보트 (Lv.2)" /><published>2026-03-13T12:13:00+00:00</published><updated>2026-03-13T12:13:00+00:00</updated><id>https://munjjang9.github.io/codingtest/2026/03/13/PS-%EA%B5%AC%EB%AA%85%EB%B3%B4%ED%8A%B8</id><content type="html" xml:base="https://munjjang9.github.io/codingtest/2026/03/13/PS-%EA%B5%AC%EB%AA%85%EB%B3%B4%ED%8A%B8/"><![CDATA[<h2 id="문제-링크">문제 링크</h2>
<hr />
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42885">프로그래머스 - 구명보트</a></p>

<p><br /></p>

<h2 id="문제-설명">문제 설명</h2>
<hr />
<p>무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다.</p>

<p>예를 들어, 사람들의 몸무게가 [70, 50, 80, 50]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없습니다.</p>

<p>구명보트를 최대한 적게 사용하여 모든 사람을 구출하려고 합니다.</p>

<p>사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성해주세요.</p>

<p><strong>제한사항</strong></p>
<ul>
  <li>무인도에 갇힌 사람은 1명 이상 50,000명 이하입니다.</li>
  <li>각 사람의 몸무게는 40 kg 이상 240 kg 이하입니다.</li>
  <li>구명보트의 무게 제한은 40 kg 이상 240 kg 이하입니다.</li>
  <li>구명보트의 무게 제한은 항상 사람들의 몸무게 중 최댓값보다 크므로, 모든 사람을 구출할 수 있습니다.</li>
</ul>

<p><br /></p>

<h2 id="내-풀이">내 풀이</h2>
<hr />
<p>오름차순 정렬 후 양 끝 포인터(<code class="language-plaintext highlighter-rouge">low</code>, <code class="language-plaintext highlighter-rouge">high</code>)를 이용했다.</p>

<p><code class="language-plaintext highlighter-rouge">high</code>는 현재 가장 무거운 사람, <code class="language-plaintext highlighter-rouge">low</code>는 가장 가벼운 사람을 가리킨다. 둘의 합이 <code class="language-plaintext highlighter-rouge">limit</code> 이하면 같이 탈 수 있으므로 <code class="language-plaintext highlighter-rouge">low++</code>로 가벼운 쪽을 한 명 처리한다. 합이 <code class="language-plaintext highlighter-rouge">limit</code>를 초과하면 무거운 사람은 혼자 탄다. 어느 경우든 <code class="language-plaintext highlighter-rouge">high--</code>와 <code class="language-plaintext highlighter-rouge">boats++</code>는 항상 실행된다.</p>

<p><code class="language-plaintext highlighter-rouge">low &gt; high</code>가 되면 모든 사람을 처리한 것이므로 종료하고 <code class="language-plaintext highlighter-rouge">boats</code>를 반환한다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="cp">
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">solution</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">people</span><span class="p">,</span> <span class="kt">int</span> <span class="n">limit</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sort</span><span class="p">(</span><span class="n">people</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">people</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
    
    <span class="kt">int</span> <span class="n">low</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">high</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">people</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">boats</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    
    <span class="k">while</span><span class="p">(</span><span class="n">low</span> <span class="o">&lt;=</span> <span class="n">high</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span><span class="p">(</span><span class="n">people</span><span class="p">[</span><span class="n">high</span><span class="p">]</span> <span class="o">+</span> <span class="n">people</span><span class="p">[</span><span class="n">low</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">limit</span><span class="p">)</span> <span class="n">low</span><span class="o">++</span><span class="p">;</span>
        
        <span class="n">high</span><span class="o">--</span><span class="p">;</span>
        <span class="n">boats</span><span class="o">++</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="n">boats</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<h2 id="시간복잡도-분석">시간복잡도 분석</h2>
<hr />
<ul>
  <li>정렬: O(N log N)</li>
  <li>while 루프: <code class="language-plaintext highlighter-rouge">high</code>는 매 반복마다 1씩 감소, <code class="language-plaintext highlighter-rouge">low</code>는 최대 N번 증가 → O(N)</li>
  <li>전체: <strong>O(N log N)</strong></li>
</ul>

<p>제한사항에서 N ≤ 50,000이므로 50,000 × log(50,000) ≈ <strong>80만 연산</strong>으로 충분히 통과 가능하다.</p>

<p><br /></p>

<h2 id="후기">후기</h2>
<hr />
<p>오늘 같이 풀었던 체육복 문제보다 오히려 구명보트 문제가 더 쉬웠던 것 같다. 레벨 1도 레벨 1 나름이고, 레벨 2도 레벨 2 나름인 것 같다.</p>]]></content><author><name>munjjang9</name></author><category term="CodingTest" /><category term="Algorithm" /><category term="CodingTest" /><category term="Greedy" /><summary type="html"><![CDATA[문제 링크 프로그래머스 - 구명보트]]></summary></entry><entry><title type="html">[프로그래머스] 체육복 (Lv.1)</title><link href="https://munjjang9.github.io/codingtest/2026/03/13/PS-%EC%B2%B4%EC%9C%A1%EB%B3%B5/" rel="alternate" type="text/html" title="[프로그래머스] 체육복 (Lv.1)" /><published>2026-03-13T12:12:00+00:00</published><updated>2026-03-13T12:12:00+00:00</updated><id>https://munjjang9.github.io/codingtest/2026/03/13/PS-%EC%B2%B4%EC%9C%A1%EB%B3%B5</id><content type="html" xml:base="https://munjjang9.github.io/codingtest/2026/03/13/PS-%EC%B2%B4%EC%9C%A1%EB%B3%B5/"><![CDATA[<h2 id="문제-링크">문제 링크</h2>
<hr />
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42862">프로그래머스 - 체육복</a></p>

<p><br /></p>

<h2 id="문제-설명">문제 설명</h2>
<hr />
<p>점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다.</p>

<p>체육복이 없으면 체육수업을 들을 수 없어서 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.</p>

<p>전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.</p>

<p><strong>제한사항</strong></p>
<ul>
  <li>전체 학생의 수는 2명 이상 30명 이하입니다.</li>
  <li>체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.</li>
  <li>여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.</li>
  <li>여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.</li>
  <li>여벌 체육복을 가져온 학생이 체육복을 도난당했을 수도 있습니다. 이 때 이 학생은 체육복을 하나밖에 없으므로 다른 학생에게는 체육복을 빌려줄 수 없습니다.</li>
</ul>

<p><br /></p>

<h2 id="내-풀이">내 풀이</h2>
<hr />
<p>전처리 단계와 대여 단계로 나눠서 풀었다.</p>

<p><strong>전처리 단계:</strong> <code class="language-plaintext highlighter-rouge">reserve</code>를 순회하며 <code class="language-plaintext highlighter-rouge">lost</code>에 같은 번호가 있으면 해당 학생은 자기 여벌을 직접 쓰는 것으로 처리해 <code class="language-plaintext highlighter-rouge">lost</code>에서 제거한다. 이 학생은 다른 사람에게 빌려줄 수 없으므로 <code class="language-plaintext highlighter-rouge">filtered_reserve</code>에 추가하지 않는다. <code class="language-plaintext highlighter-rouge">lost</code>에 없는 학생만 <code class="language-plaintext highlighter-rouge">filtered_reserve</code>에 추가해 순수하게 빌려줄 수 있는 학생 목록을 만든다.</p>

<p><strong>대여 단계:</strong> <code class="language-plaintext highlighter-rouge">filtered_reserve</code>의 각 학생이 번호 ±1인 학생에게 빌려줄 수 있는지 확인한다. 앞번호(r-1) 우선으로 찾고, 없으면 뒷번호(r+1)를 찾아 <code class="language-plaintext highlighter-rouge">lost</code>에서 제거한다.</p>

<p>최종적으로 <code class="language-plaintext highlighter-rouge">n - lost.size()</code>를 반환하면 체육복이 있는 학생 수가 된다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="cp">
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">solution</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">lost</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">reserve</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sort</span><span class="p">(</span><span class="n">lost</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">lost</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
    <span class="n">sort</span><span class="p">(</span><span class="n">reserve</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">reserve</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
    
    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">filtered_reserve</span><span class="p">;</span>
    
    <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">r</span> <span class="o">:</span> <span class="n">reserve</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">lost</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">lost</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">r</span><span class="p">);</span>
        <span class="k">if</span><span class="p">(</span><span class="n">it</span> <span class="o">!=</span> <span class="n">lost</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
            <span class="n">lost</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">it</span><span class="p">);</span>
        <span class="k">else</span>
            <span class="n">filtered_reserve</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">r</span><span class="p">);</span>
    <span class="p">}</span>
    
    <span class="n">reserve</span> <span class="o">=</span> <span class="n">filtered_reserve</span><span class="p">;</span>
    
    <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">r</span> <span class="o">:</span> <span class="n">reserve</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">lost</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">lost</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">r</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
        <span class="k">if</span><span class="p">(</span><span class="n">it</span> <span class="o">==</span> <span class="n">lost</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
            <span class="n">it</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">lost</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">lost</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">r</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
        <span class="k">if</span><span class="p">(</span><span class="n">it</span> <span class="o">!=</span> <span class="n">lost</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
            <span class="n">lost</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">it</span><span class="p">);</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="n">n</span> <span class="o">-</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">lost</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<h2 id="시간복잡도-분석">시간복잡도 분석</h2>
<hr />
<ul>
  <li>정렬: O(L log L + R log R) — L = lost 크기, R = reserve 크기</li>
  <li>전처리 루프: reserve 각 원소마다 find(O(L)) → O(R × L)</li>
  <li>대여 루프: reserve 각 원소마다 find 최대 2회(O(L)) → O(R × L)</li>
  <li>전체: <strong>O(R × L)</strong></li>
</ul>

<p>제한사항에서 n ≤ 30이므로 L, R ≤ 30. 최악의 경우 30 × 30 = <strong>900번 연산</strong>으로 충분히 통과 가능하다.</p>

<p><br /></p>

<h2 id="오답노트">오답노트</h2>
<hr />
<p>처음 제출 시 83.3%가 나왔다.</p>

<p>원인은 <code class="language-plaintext highlighter-rouge">lost</code>와 <code class="language-plaintext highlighter-rouge">reserve</code>에 <strong>동시에 존재하는 학생</strong>을 처리하지 않은 것이었다. 예를 들어 <code class="language-plaintext highlighter-rouge">lost=[2,4], reserve=[2,3]</code>일 때, 2번 학생은 도난당했지만 여벌도 있으므로 자기 것을 쓰면 된다. 그런데 이 처리 없이 그냥 진행하면 3번 학생이 2번에게 빌려주게 되고, 정작 4번 학생은 아무도 빌려주지 못하는 문제가 생겼다.</p>

<p>수정하는 과정에서도 실수가 있었다. <code class="language-plaintext highlighter-rouge">for(int r : reserve)</code> 루프 안에서 <code class="language-plaintext highlighter-rouge">reserve.erase(it)</code>를 시도했는데, <code class="language-plaintext highlighter-rouge">it</code>가 <code class="language-plaintext highlighter-rouge">lost</code>의 이터레이터였고, 순회 중인 컨테이너를 직접 수정하면 UB가 발생한다. <code class="language-plaintext highlighter-rouge">filtered_reserve</code>를 별도로 만들어 순회 중 수정 없이 처리하는 방식으로 해결했다.</p>

<p><br /></p>

<h2 id="후기">후기</h2>
<hr />
<p>탐욕법을 들어만 봤지, 제대로 공부하고 응용해본 것은 오늘이 처음이었다. 사실 아직까지는 어떤 문제가 탐욕이 적용 가능한지 구별해낼 자신은 없지만, 하다보면 늘 거라고 생각한다.</p>]]></content><author><name>munjjang9</name></author><category term="CodingTest" /><category term="Algorithm" /><category term="CodingTest" /><category term="Greedy" /><summary type="html"><![CDATA[문제 링크 프로그래머스 - 체육복]]></summary></entry><entry><title type="html">탐욕법 (Greedy)</title><link href="https://munjjang9.github.io/algorithm/2026/03/13/Greedy/" rel="alternate" type="text/html" title="탐욕법 (Greedy)" /><published>2026-03-13T10:12:00+00:00</published><updated>2026-03-13T10:12:00+00:00</updated><id>https://munjjang9.github.io/algorithm/2026/03/13/Greedy</id><content type="html" xml:base="https://munjjang9.github.io/algorithm/2026/03/13/Greedy/"><![CDATA[<h2 id="전날-내용-요약--완전탐색-brute-force">전날 내용 요약 — 완전탐색 (Brute Force)</h2>

<ul>
  <li>완전탐색은 모든 경우를 다 시도해 정답을 보장하는 전략 — “무식한 방법”이 아닌 “보장된 정답”</li>
  <li><code class="language-plaintext highlighter-rouge">next_permutation</code>: 반드시 오름차순 정렬 후 사용해야 모든 순열을 얻을 수 있음</li>
  <li>조합 재귀에서 <code class="language-plaintext highlighter-rouge">start</code> 파라미터로 중복을 막음 — <code class="language-plaintext highlighter-rouge">i+1</code>을 넘겨 항상 앞에서 뒤 방향으로만 선택</li>
  <li>비트마스크 부분집합: <code class="language-plaintext highlighter-rouge">mask &amp; (1 &lt;&lt; i)</code>로 i번째 원소 선택 여부 판단, 경우의 수 2^N</li>
  <li>시간복잡도 기준: 순열 N ≤ 8, 부분집합 N ≤ 20, 이중반복문 N ≤ 10,000</li>
</ul>

<hr />

<h2 id="탐욕법이란">탐욕법이란?</h2>

<p>완전 탐색은 모든 경우를 다 보는 방법이지만 n이 커지면 시간초과가 발생한다.<br />
반면, 탐욕법은 매 순간 현재 시점에서 가장 최선의 선택을 하는 방법이다.</p>

<p>탐욕법을 사용하면 전체 경우를 다 보지 않더라도 최적해에 도달할 수 있다.</p>

<hr />

<h2 id="탐욕법의-적용-조건">탐욕법의 적용 조건</h2>

<ol>
  <li>탐욕 선택 속성 -&gt; 현재의 최선의 선택이 미래에도 최선을 보장하는 경우</li>
</ol>

<ul>
  <li>
    <p>예시 (보트 타기) : 가장 무거운 사람과 가장 가벼운 사람을 보트에 태움 -&gt; 이 선택이 나중의 선택에도 여전히 최선</p>
  </li>
  <li>
    <p>반례 (최소 동전 개수) : 1원, 4원, 6원 동전이 있고 8원을 만들어야 할 때. -&gt; 큰 숫자를 만들기 위한 최선의 선택은 큰 숫자를 고르는 것. 하지만, 6원을 고르면 1원 2개를 골라야 해서 3개의 동전이 필요하다. 4원을 2개 고르는 것이 최선의 선택.</p>
  </li>
</ul>

<ol>
  <li>최적 부분 구조 -&gt; 부분 문제의 최적해가 모여 전체 최적해를 이루는 경우</li>
</ol>

<ul>
  <li>예시 (짐 싣기) : n개의 짐을 싣는데 필요한 최소 트럭 수 = (첫 번째 짝 선택) + (나머지 n-2개 짐의 최소 트럭 수). 이처럼 작은 문제(n-2개)의 최적해가 전체 최적해에 기여하는 경우.</li>
</ul>

<blockquote>
  <p>위 조건들이 성립하지 않으면 탐욕은 오답을 낼 수 있음.</p>
</blockquote>

<hr />

<h2 id="패턴-1--정렬-후-순서대로-선택">패턴 1 — 정렬 후 순서대로 선택</h2>

<p>가장 흔한 탐욕 패턴이다. 기준에 따라 정렬한 뒤 앞에서부터 차례로 선택한다.</p>

<p>예시) 과자 나눠주기
각각 원하는 최소 과자 크기가 있는 어린이들이 있고, 크기 별로 과자가 존재.
이 때 최대 몇 명을 만족시킬 수 있는지를 해결하는 문제.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">assignCookies</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">children</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">cookies</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sort</span><span class="p">(</span><span class="n">children</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">children</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
    <span class="n">sort</span><span class="p">(</span><span class="n">cookies</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">cookies</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>

    <span class="kt">int</span> <span class="n">child</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">cookie</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">child</span> <span class="o">&lt;</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">children</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">cookie</span> <span class="o">&lt;</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">cookies</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">cookies</span><span class="p">[</span><span class="n">cookie</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="n">children</span><span class="p">[</span><span class="n">child</span><span class="p">])</span>
            <span class="n">child</span><span class="o">++</span><span class="p">;</span>   <span class="c1">// 만족 → 다음 어린이로</span>
        <span class="n">cookie</span><span class="o">++</span><span class="p">;</span>      <span class="c1">// 과자는 무조건 다음으로</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">child</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<hr />

<h2 id="패턴-2--양쪽에서-좁혀오기">패턴 2 — 양쪽에서 좁혀오기</h2>

<p>정렬을 한 후 양 끝 포인터를 이용해 최적 쌍을 선택하는 방법</p>

<p>예시) 한 번에 짐을 최대 두 개까지 싣는 것이 가능한 수레가 있다. 두 짐의 무게 합은 limit을 넘지 않아야 할 때, 필요한 최소 수레의 수는?</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">loadWagon</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">weights</span><span class="p">,</span> <span class="kt">int</span> <span class="n">limit</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sort</span><span class="p">(</span><span class="n">weights</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">weights</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>

    <span class="kt">int</span> <span class="n">lo</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">hi</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">weights</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">wagons</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="k">while</span> <span class="p">(</span><span class="n">lo</span> <span class="o">&lt;=</span> <span class="n">hi</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// 가장 가벼운 짐 + 가장 무거운 짐을 같이 실을 수 있으면 같이 싣는다</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">weights</span><span class="p">[</span><span class="n">lo</span><span class="p">]</span> <span class="o">+</span> <span class="n">weights</span><span class="p">[</span><span class="n">hi</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">limit</span><span class="p">)</span>
            <span class="n">lo</span><span class="o">++</span><span class="p">;</span>
        <span class="n">hi</span><span class="o">--</span><span class="p">;</span>      <span class="c1">// 가장 무거운 짐은 항상 수레 1대 소모</span>
        <span class="n">wagons</span><span class="o">++</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">wagons</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<hr />

<h2 id="탐욕-vs-완전탐색-판단법">탐욕 vs 완전탐색 판단법</h2>

<table>
  <thead>
    <tr>
      <th>기준</th>
      <th>완전탐색</th>
      <th>탐욕</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>N 크기</td>
      <td>작음 (≤ 20)</td>
      <td>큼 (≤ 100,000)</td>
    </tr>
    <tr>
      <td>정확성</td>
      <td>항상 보장</td>
      <td>증명/직관 필요</td>
    </tr>
    <tr>
      <td>시간복잡도</td>
      <td>O(N!), O(2^N)</td>
      <td>O(N log N) 수준</td>
    </tr>
    <tr>
      <td>적용 조건</td>
      <td>제한 없음</td>
      <td>탐욕 선택 속성 성립 시</td>
    </tr>
  </tbody>
</table>

<p><strong>판단하는 순서</strong></p>
<ol>
  <li>n이 크면 완전탐색은 불가능 -&gt; 탐욕 or DP를 고려</li>
  <li>정렬 후 순서대로 선택하면 최적인가를 직관적으로 판단</li>
  <li>반례를 하나라도 찾으면 탐욕 불가능 -&gt; DP</li>
</ol>

<hr />

<h2 id="시간복잡도">시간복잡도</h2>

<p>탐욕법 자체는 O(N)이지만, 정렬이 필요하면 <strong>O(N log N)</strong> 이 된다.</p>

<table>
  <thead>
    <tr>
      <th>단계</th>
      <th>시간복잡도</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>정렬</td>
      <td>O(N log N)</td>
    </tr>
    <tr>
      <td>탐욕 선택 (단일 패스)</td>
      <td>O(N)</td>
    </tr>
    <tr>
      <td>전체</td>
      <td><strong>O(N log N)</strong></td>
    </tr>
  </tbody>
</table>]]></content><author><name>munjjang9</name></author><category term="Algorithm" /><category term="Algorithm" /><category term="Greedy" /><category term="C++" /><summary type="html"><![CDATA[전날 내용 요약 — 완전탐색 (Brute Force)]]></summary></entry><entry><title type="html">[프로그래머스] 최소직사각형 (Lv.1)</title><link href="https://munjjang9.github.io/codingtest/2026/03/12/PS-%EC%B5%9C%EC%86%8C%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95/" rel="alternate" type="text/html" title="[프로그래머스] 최소직사각형 (Lv.1)" /><published>2026-03-12T13:00:00+00:00</published><updated>2026-03-12T13:00:00+00:00</updated><id>https://munjjang9.github.io/codingtest/2026/03/12/PS-%EC%B5%9C%EC%86%8C%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95</id><content type="html" xml:base="https://munjjang9.github.io/codingtest/2026/03/12/PS-%EC%B5%9C%EC%86%8C%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95/"><![CDATA[<h2 id="문제-링크">문제 링크</h2>
<hr />
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/86491">프로그래머스 - 최소직사각형</a></p>

<p><br /></p>

<h2 id="문제-설명">문제 설명</h2>
<hr />
<p>명함 지갑을 만드는 회사에서 지갑의 크기를 정하려고 합니다. 다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다.</p>

<p>각 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes가 매개변수로 주어집니다. 모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return 하도록 solution 함수를 완성해주세요.</p>

<p><strong>제한사항</strong></p>
<ul>
  <li>sizes의 길이는 1 이상 10,000 이하입니다.</li>
  <li>sizes의 각 원소는 [w, h] 형식입니다.</li>
  <li>w는 명함의 가로 길이를 나타냅니다.</li>
  <li>h는 명함의 세로 길이를 나타냅니다.</li>
  <li>w와 h는 1 이상 1,000 이하인 자연수입니다.</li>
</ul>

<p><br /></p>

<h2 id="내-풀이">내 풀이</h2>
<hr />
<p>모든 명함을 긴 쪽이 가로(<code class="language-plaintext highlighter-rouge">card[0]</code>), 짧은 쪽이 세로(<code class="language-plaintext highlighter-rouge">card[1]</code>)가 되도록 방향을 통일한다.
그 후 모든 명함의 가로 최댓값과 세로 최댓값을 구해 곱하면 최소 지갑 크기가 된다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">solution</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">sizes</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">w</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">h</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    
    <span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">card</span> <span class="o">:</span> <span class="n">sizes</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span><span class="p">(</span><span class="n">card</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">card</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
            <span class="n">swap</span><span class="p">(</span><span class="n">card</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">card</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
    <span class="p">}</span>
    
    <span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">card</span> <span class="o">:</span> <span class="n">sizes</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span><span class="p">(</span><span class="n">w</span> <span class="o">&lt;</span> <span class="n">card</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="n">w</span> <span class="o">=</span> <span class="n">card</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
        <span class="k">if</span><span class="p">(</span><span class="n">h</span> <span class="o">&lt;</span> <span class="n">card</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="n">h</span> <span class="o">=</span> <span class="n">card</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="n">w</span> <span class="o">*</span> <span class="n">h</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<h2 id="시간복잡도-분석">시간복잡도 분석</h2>
<hr />
<ul>
  <li>방향 통일 반복문: O(N)</li>
  <li>최댓값 탐색 반복문: O(N)</li>
  <li>전체: <strong>O(N)</strong>, N = sizes 크기 (최대 10,000)</li>
</ul>

<p>N ≤ 10,000이므로 충분히 통과 가능하다.</p>

<p><br /></p>

<h2 id="오답노트">오답노트</h2>
<hr />
<p>처음에는 어떻게 접근해야 할지 감이 잡히지 않았다.</p>

<p>핵심 아이디어는 <strong>모든 명함의 방향을 통일</strong>하는 것이다. 명함은 회전이 가능하므로, 긴 쪽을 항상 가로로 맞추면 지갑의 가로 = 모든 명함 가로의 최댓값, 세로 = 모든 명함 세로의 최댓값으로 단순화된다.</p>

<p>방향을 통일하지 않고 그냥 최댓값을 구하면 불필요하게 큰 지갑이 나오게 된다.</p>

<p><br /></p>

<h2 id="후기">후기</h2>
<hr />
<!-- 풀면서 느낀 점, 다른 풀이 방법 등 -->]]></content><author><name>munjjang9</name></author><category term="CodingTest" /><category term="Algorithm" /><category term="CodingTest" /><category term="BruteForce" /><summary type="html"><![CDATA[문제 링크 프로그래머스 - 최소직사각형]]></summary></entry><entry><title type="html">[프로그래머스] 약수의 개수와 덧셈 (Lv.1)</title><link href="https://munjjang9.github.io/codingtest/2026/03/12/PS-%EC%95%BD%EC%88%98%EC%9D%98%EA%B0%9C%EC%88%98%EC%99%80%EB%8D%A7%EC%85%88/" rel="alternate" type="text/html" title="[프로그래머스] 약수의 개수와 덧셈 (Lv.1)" /><published>2026-03-12T12:40:00+00:00</published><updated>2026-03-12T12:40:00+00:00</updated><id>https://munjjang9.github.io/codingtest/2026/03/12/PS-%EC%95%BD%EC%88%98%EC%9D%98%EA%B0%9C%EC%88%98%EC%99%80%EB%8D%A7%EC%85%88</id><content type="html" xml:base="https://munjjang9.github.io/codingtest/2026/03/12/PS-%EC%95%BD%EC%88%98%EC%9D%98%EA%B0%9C%EC%88%98%EC%99%80%EB%8D%A7%EC%85%88/"><![CDATA[<h2 id="문제-링크">문제 링크</h2>
<hr />
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/77884">프로그래머스 - 약수의 개수와 덧셈</a></p>

<p><br /></p>

<h2 id="문제-설명">문제 설명</h2>
<hr />
<p>두 정수 left와 right가 매개변수로 주어집니다. left부터 right까지의 모든 수들 중에서, 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 빼려고 합니다. 그 결과를 return 하도록 solution 함수를 완성해주세요.</p>

<p><strong>제한사항</strong></p>
<ul>
  <li>1 ≤ left ≤ right ≤ 1,000</li>
</ul>

<p><br /></p>

<h2 id="내-풀이">내 풀이</h2>
<hr />
<p>left부터 right까지 각 수를 순회하며, 1부터 해당 수까지 나누어 약수의 개수를 센다.
약수 개수가 짝수면 answer에 더하고, 홀수면 뺀다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">solution</span><span class="p">(</span><span class="kt">int</span> <span class="n">left</span><span class="p">,</span> <span class="kt">int</span> <span class="n">right</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">answer</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">left</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">right</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">int</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;=</span> <span class="n">i</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">%</span> <span class="n">j</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="n">count</span><span class="o">++</span><span class="p">;</span>
        <span class="p">}</span>
        
        <span class="k">if</span><span class="p">(</span><span class="n">count</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">answer</span> <span class="o">+=</span> <span class="n">i</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">else</span>
        <span class="p">{</span>
            <span class="n">answer</span> <span class="o">-=</span> <span class="n">i</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="n">answer</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<h2 id="시간복잡도-분석">시간복잡도 분석</h2>
<hr />
<ul>
  <li>외부 루프: O(right - left + 1) ≤ O(1,000)</li>
  <li>내부 루프 (약수 탐색): O(i) ≤ O(1,000)</li>
  <li>전체: <strong>O(N²)</strong>, N = right - left + 1 (최대 1,000)</li>
</ul>

<p>최대 약 1,000,000번 연산 → 충분히 통과 가능하다.</p>

<p><br /></p>

<h2 id="후기">후기</h2>
<hr />
<!-- 풀면서 느낀 점, 다른 풀이 방법 등 -->]]></content><author><name>munjjang9</name></author><category term="CodingTest" /><category term="Algorithm" /><category term="CodingTest" /><category term="BruteForce" /><summary type="html"><![CDATA[문제 링크 프로그래머스 - 약수의 개수와 덧셈]]></summary></entry><entry><title type="html">[프로그래머스] 문자열 내 p와 y의 개수 (Lv.1)</title><link href="https://munjjang9.github.io/codingtest/2026/03/12/PS-%EB%AC%B8%EC%9E%90%EC%97%B4%EB%82%B4p%EC%99%80y%EC%9D%98%EA%B0%9C%EC%88%98/" rel="alternate" type="text/html" title="[프로그래머스] 문자열 내 p와 y의 개수 (Lv.1)" /><published>2026-03-12T12:30:00+00:00</published><updated>2026-03-12T12:30:00+00:00</updated><id>https://munjjang9.github.io/codingtest/2026/03/12/PS-%EB%AC%B8%EC%9E%90%EC%97%B4%EB%82%B4p%EC%99%80y%EC%9D%98%EA%B0%9C%EC%88%98</id><content type="html" xml:base="https://munjjang9.github.io/codingtest/2026/03/12/PS-%EB%AC%B8%EC%9E%90%EC%97%B4%EB%82%B4p%EC%99%80y%EC%9D%98%EA%B0%9C%EC%88%98/"><![CDATA[<h2 id="문제-링크">문제 링크</h2>
<hr />
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/12916">프로그래머스 - 문자열 내 p와 y의 개수</a></p>

<p><br /></p>

<h2 id="문제-설명">문제 설명</h2>
<hr />
<p>대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 ‘p’의 개수와 ‘y’의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. ‘p’, ‘y’ 모두 하나도 없는 경우는 같은 개수로 처리합니다.</p>

<p>단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다.</p>

<p><strong>제한사항</strong></p>
<ul>
  <li>문자열 s의 길이 : 50 이하의 자연수</li>
  <li>문자열 s는 알파벳으로만 이루어져 있습니다.</li>
</ul>

<p><br /></p>

<h2 id="내-풀이">내 풀이</h2>
<hr />
<p>문자열을 순회하며 <code class="language-plaintext highlighter-rouge">p</code>/<code class="language-plaintext highlighter-rouge">P</code>와 <code class="language-plaintext highlighter-rouge">y</code>/<code class="language-plaintext highlighter-rouge">Y</code>의 개수를 각각 카운트한다.
두 개수가 같으면 <code class="language-plaintext highlighter-rouge">true</code>, 다르면 <code class="language-plaintext highlighter-rouge">false</code>를 반환한다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="kt">bool</span> <span class="nf">solution</span><span class="p">(</span><span class="n">string</span> <span class="n">s</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">count_p</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">count_y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="k">for</span><span class="p">(</span><span class="kt">char</span> <span class="n">c</span> <span class="o">:</span> <span class="n">s</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span><span class="p">(</span><span class="n">c</span> <span class="o">==</span> <span class="sc">'p'</span> <span class="o">||</span> <span class="n">c</span> <span class="o">==</span> <span class="sc">'P'</span><span class="p">)</span> <span class="n">count_p</span><span class="o">++</span><span class="p">;</span>
        <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">c</span> <span class="o">==</span> <span class="sc">'y'</span> <span class="o">||</span> <span class="n">c</span> <span class="o">==</span> <span class="sc">'Y'</span><span class="p">)</span> <span class="n">count_y</span><span class="o">++</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">count_p</span> <span class="o">==</span> <span class="n">count_y</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<h2 id="시간복잡도-분석">시간복잡도 분석</h2>
<hr />
<ul>
  <li>문자열 순회: O(N), N = 문자열 길이 (최대 50)</li>
  <li>전체: <strong>O(N)</strong></li>
</ul>

<p>N ≤ 50이므로 사실상 제한 없이 통과 가능하다.</p>

<p><br /></p>

<h2 id="후기">후기</h2>
<hr />
<p>이건 너무 쉬운 문제를 고른 것 같다… 이 문제는 약간 레벨 0 느낌..?</p>]]></content><author><name>munjjang9</name></author><category term="CodingTest" /><category term="Algorithm" /><category term="CodingTest" /><category term="BruteForce" /><summary type="html"><![CDATA[문제 링크 프로그래머스 - 문자열 내 p와 y의 개수]]></summary></entry><entry><title type="html">완전탐색 (Brute Force)</title><link href="https://munjjang9.github.io/algorithm/2026/03/12/BruteForce/" rel="alternate" type="text/html" title="완전탐색 (Brute Force)" /><published>2026-03-12T12:00:00+00:00</published><updated>2026-03-12T12:00:00+00:00</updated><id>https://munjjang9.github.io/algorithm/2026/03/12/BruteForce</id><content type="html" xml:base="https://munjjang9.github.io/algorithm/2026/03/12/BruteForce/"><![CDATA[<h2 id="전날-내용-요약--정렬-sort">전날 내용 요약 — 정렬 (Sort)</h2>

<ul>
  <li><code class="language-plaintext highlighter-rouge">std::sort</code>: 평균 O(N log N) 인트로소트 (퀵소트+힙소트+삽입소트 하이브리드)</li>
  <li>커스텀 비교 함수 작성 시 Strict Weak Ordering 준수 — 같은 원소끼리는 반드시 <code class="language-plaintext highlighter-rouge">false</code> 반환</li>
  <li>다중 정렬 기준: <code class="language-plaintext highlighter-rouge">if (a.x != b.x) return ...; return ...;</code> 패턴</li>
  <li><code class="language-plaintext highlighter-rouge">stable_sort</code>: 동일 원소의 원래 순서 보장, O(N log² N)</li>
</ul>

<hr />

<h2 id="완전탐색이란">완전탐색이란?</h2>

<p>가능한 모든 경우의 수를 다 시도해서 정답을 찾는 방법이다.</p>

<p>복잡한 최적화를 거치지 않아도 정답을 보장하며, 입력 크기가 작은 경우에는 항상 유효한 선택지가 된다.</p>

<p>시간복잡도를 계산해서 통과가 가능하다면 다른 복잡한 알고리즘을 쓰는 것보다 완전탐색으로 풀 수 있는지 확인하는 전략을 취하는 것이 좋다.</p>

<hr />

<h2 id="기본-반복문-완전탐색">기본 반복문 완전탐색</h2>

<p>배열에서 두 수의 합이 target인 쌍을 찾는 방법을 예시로 들었다.</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="n">v</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">v</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">==</span> <span class="n">target</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// 찾음</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이 경우, 시간복잡도는 O(n²)이며, n이 10,000이하인 경우 1초 안에 통과가 가능하다.</p>

<hr />

<h2 id="순열--next_permutation">순열 — next_permutation</h2>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">v</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">};</span>

<span class="c1">// 반드시 오름차순 정렬 후 시작해야 모든 순열을 얻을 수 있다.</span>
<span class="n">sort</span><span class="p">(</span><span class="n">v</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">v</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>

<span class="k">do</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">x</span> <span class="o">:</span> <span class="n">v</span><span class="p">)</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">x</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span>
    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">next_permutation</span><span class="p">(</span><span class="n">v</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">v</span><span class="p">.</span><span class="n">end</span><span class="p">()));</span>
</code></pre></div></div>

<p>경우의 수는 n!이다.</p>

<p>이 경우에는 시간복잡도가 O(n * n!)이므로, n이 8~9 이하인 경우에만 통과가 가능하다.</p>

<hr />

<h2 id="조합--재귀-구현">조합 — 재귀 구현</h2>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">combination</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">nums</span><span class="p">,</span> <span class="kt">int</span> <span class="n">r</span><span class="p">,</span> <span class="kt">int</span> <span class="n">start</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="n">chosen</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="n">r</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">x</span> <span class="o">:</span> <span class="n">chosen</span><span class="p">)</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">x</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
        <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">start</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">nums</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">chosen</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
        <span class="n">combination</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
        <span class="n">chosen</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>start 파라미터에 i+1이 전달되면서 항상 현재 선택한 원소보다 뒤에 있는 원소만을 선택 가능하게 한다. 이 덕분에 다른 중복 조합이 생기지 않는다.</p>

<hr />

<h2 id="부분집합--비트마스크">부분집합 — 비트마스크</h2>

<p>n개의 원소로 만들 수 있는 모든 부분집합을 열거하는 방식이다.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">v</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="n">v</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>

<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">mask</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">mask</span> <span class="o">&lt;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">n</span><span class="p">);</span> <span class="n">mask</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"{ "</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">mask</span> <span class="o">&amp;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">i</span><span class="p">))</span> <span class="p">{</span> <span class="c1">//i번째 비트가 1이면</span>
            <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">v</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"}</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이 경우에는 O(n * 2^n)정도의 시간복잡도를 가지기 때문에 n이 20이하인 경우에는 안전하게 통과가 가능하다.</p>

<hr />

<h2 id="시간복잡도-정리">시간복잡도 정리</h2>

<table>
  <thead>
    <tr>
      <th>유형</th>
      <th>경우의 수</th>
      <th>N의 실용적 한계</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>순열 (N!)</td>
      <td>N!</td>
      <td>N ≤ 8 (40,320)</td>
    </tr>
    <tr>
      <td>조합 C(N,R)</td>
      <td>N! / R!(N-R)!</td>
      <td>N ≤ 25 수준</td>
    </tr>
    <tr>
      <td>부분집합 (2^N)</td>
      <td>2^N</td>
      <td>N ≤ 20 (1,048,576)</td>
    </tr>
    <tr>
      <td>이중 반복문 (N²)</td>
      <td>N²</td>
      <td>N ≤ 10,000</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="완전탐색-풀이-전략">완전탐색 풀이 전략</h2>

<ol>
  <li>n의 크기를 먼저 확인한다.(시간복잡도 계산)</li>
  <li>유형을 분류한다
    <ul>
      <li>순서O -&gt; 순열</li>
      <li>순서X -&gt; 조합(재귀)</li>
      <li>선택/미선택 -&gt; 부분집합(비트마스크)</li>
      <li>격자 탐색 -&gt; DFS/BFS</li>
    </ul>
  </li>
  <li>Pruning(불필요한 탐색 조기 종료)</li>
</ol>]]></content><author><name>munjjang9</name></author><category term="Algorithm" /><category term="Algorithm" /><category term="BruteForce" /><category term="C++" /><summary type="html"><![CDATA[전날 내용 요약 — 정렬 (Sort)]]></summary></entry></feed>