<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>김치만두 먹고 공부하기</title>
    <link>https://haram17-devlog.tistory.com/</link>
    <description>개발 블로그</description>
    <language>ko</language>
    <pubDate>Thu, 9 Jul 2026 06:22:11 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>꿀꺽람</managingEditor>
    <image>
      <title>김치만두 먹고 공부하기</title>
      <url>https://tistory1.daumcdn.net/tistory/4927012/attach/0d4c048f3d2441bf8a6445bce2fd9424</url>
      <link>https://haram17-devlog.tistory.com</link>
    </image>
    <item>
      <title>[2. 트리, 힙, 그래프] 힙</title>
      <link>https://haram17-devlog.tistory.com/69</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;힙(Heap)&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;힙의 특징은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 최대 원소에 즉각적으로 접근할 수 있다. O(1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 원소 삽입과 삭제에 대해 O(logN)의 시간복잡도를 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 특징을 만족하기 위해&lt;b&gt; 완전이진트리(Complete Binary Tree)&lt;/b&gt;를 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 완전 이진트리: 마지막 레벨의 노드를 제외하고는 모두 두 개의 자식이 있고, 마지막 레벨에서는 왼쪽부터 차례대로 노드 존재&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dr09zT/btr3LrHqhRi/SSZXpLKjmUEt5v3XQLBvXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dr09zT/btr3LrHqhRi/SSZXpLKjmUEt5v3XQLBvXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dr09zT/btr3LrHqhRi/SSZXpLKjmUEt5v3XQLBvXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdr09zT%2Fbtr3LrHqhRi%2FSSZXpLKjmUEt5v3XQLBvXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;247&quot; height=&quot;292&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1181&quot;/&gt;&lt;/span&gt;&lt;/figure&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;부모노드에서 자식노드로 이동하는 것은 배열의 인덱스 계산으로 쉽게 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 부모 노드의 인덱스가 i라면, 자식 노드의 인덱스는 2 * i + 1, 2 * i + 2이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 자식 노드의 인덱스가 i라면, 부모 노드의 인덱스는 (i - 1) / 2로 표현할 수 있다.&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;b&gt;최대 힙과 최소 힙&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 원소가 트리의 루트에 있도록 설정한 힙 -&amp;gt; 최대 힙&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소 원소가 트리의 루트에 있도록 설정한 힙 -&amp;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;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;힙 연산 (원소 삽입)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&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;b&gt;&lt;i&gt; 마지막 노드 바로 오른쪽에 새로운 노드를 추가&lt;/i&gt;&lt;/b&gt;하거나, &lt;b&gt;&lt;i&gt;새로운 레벨을 추가하여 노드를 추가&lt;/i&gt;&lt;/b&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;b&gt;모든 노드는 자식 노드보다 큰 값을 가지고 있어야 한다&lt;/b&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;그럴 때에는 새로 삽입한 원소의 부모 노드와 값을 비교하고, 부모 노드보다 해당 노드가 더 크면 서로 Swap 하는 방식으로 삽입 연산을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전 이진 트리의 높이는 최대 logN이므로, 삽입 연산의 시간 복잡도는 O(logN)으로 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;힙 연산 (원소 삭제)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&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;이렇게 하면 부모 노드가 자식 노드보다 큰 값을 만족하지 않을 수 있다.&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;힙 초기화하기&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불변성을 유지하면서 힙을 초기화하는 가장 쉬운 방법은 비어있는 힙에 원소를 하나씩 추가하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이 방법은 O(NlogN)의 시간복잡도를 가지며 그렇게 효율적인 방법은 아니다.&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;힙 생성 알고리즘을 사용하면 이를 O(N) 시간에 초기화할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 트리의 아래쪽 서브 트리부터 힙 불변성을 만족하도록 힙을 업데이트하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C++에서는 배열 또는 벡터의 반복자를 입력으로 받아 힙을 구성하는 std::make_heap() 함수를 제공하기도 한다.&lt;/p&gt;</description>
      <category>알고리즘/알고리즘 공부</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/69</guid>
      <comments>https://haram17-devlog.tistory.com/69#entry69comment</comments>
      <pubDate>Tue, 14 Mar 2023 17:48:42 +0900</pubDate>
    </item>
    <item>
      <title>[2. 트리, 힙, 그래프] 균형 트리, n항 트리</title>
      <link>https://haram17-devlog.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dev-haram.online/67&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dev-haram.online/67&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1676453494288&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[2. 트리, 힙, 그래프] 이진 검색 트리(Binary Search Tree)&quot; data-og-description=&quot;이진 검색 트리 (Binary Search Tree) 이진 검색 트리는 다음과 같은 속성을 갖는 이진 트리이다. - 부모 노드의 값 &amp;gt;= 왼쪽 자식 노드의 값 - 부모 노드의 값 18, 15 &amp;lt; 18, 17 &amp;lt; 18 이기 때문에 위 그림처럼 17&quot; data-og-host=&quot;dev-haram.online&quot; data-og-source-url=&quot;https://dev-haram.online/67&quot; data-og-url=&quot;https://dev-haram.online/67&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zoLkN/hyRCQZxqdf/SbwrdCU9JMLW08fO8k2z40/img.png?width=800&amp;amp;height=494&amp;amp;face=0_0_800_494,https://scrap.kakaocdn.net/dn/mZJXf/hyRCVT7f3d/pQ2IGKmYBTTOL18JpLJ3hK/img.png?width=800&amp;amp;height=494&amp;amp;face=0_0_800_494,https://scrap.kakaocdn.net/dn/L6v5d/hyRDTUFnuB/Wgyr488j0IMZGVEDU5Yt3k/img.png?width=1036&amp;amp;height=640&amp;amp;face=0_0_1036_640&quot;&gt;&lt;a href=&quot;https://dev-haram.online/67&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dev-haram.online/67&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zoLkN/hyRCQZxqdf/SbwrdCU9JMLW08fO8k2z40/img.png?width=800&amp;amp;height=494&amp;amp;face=0_0_800_494,https://scrap.kakaocdn.net/dn/mZJXf/hyRCVT7f3d/pQ2IGKmYBTTOL18JpLJ3hK/img.png?width=800&amp;amp;height=494&amp;amp;face=0_0_800_494,https://scrap.kakaocdn.net/dn/L6v5d/hyRDTUFnuB/Wgyr488j0IMZGVEDU5Yt3k/img.png?width=1036&amp;amp;height=640&amp;amp;face=0_0_1036_640');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[2. 트리, 힙, 그래프] 이진 검색 트리(Binary Search Tree)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이진 검색 트리 (Binary Search Tree) 이진 검색 트리는 다음과 같은 속성을 갖는 이진 트리이다. - 부모 노드의 값 &amp;gt;= 왼쪽 자식 노드의 값 - 부모 노드의 값 18, 15 &amp;lt; 18, 17 &amp;lt; 18 이기 때문에 위 그림처럼 17&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dev-haram.online&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;이를 조금 더 자세히 살펴보면,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbT2Uj/btrZtpMAVKL/QKnWNIiH8oo7lpkxFPx7nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbT2Uj/btrZtpMAVKL/QKnWNIiH8oo7lpkxFPx7nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbT2Uj/btrZtpMAVKL/QKnWNIiH8oo7lpkxFPx7nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbT2Uj%2FbtrZtpMAVKL%2FQKnWNIiH8oo7lpkxFPx7nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1072&quot; height=&quot;688&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;균형 트리 (balanced tree)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&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;이렇게 편향성이 줄어든 BST를 높이 균형 BST (height-balanced BST) 라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 트리를 만드는 방법은 여러 가지가 존재하며, 이를 통해 AVL 트리, 레드-블랙 트리 등의 다양한 트리를 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;N-항 트리&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지는 주로 이진 트리에 대해서 서술했지만, 각 노드의 자식이 두 개가 아닌 n 개의 자식을 갖는 트리를 n 항 트리라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n개의 자식 노드는 vector 컨테이너를 이용하여 저장할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1676454544218&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct nTree{
    int data;
    std::vector&amp;lt;nTree*&amp;gt; children;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터 파일 시스템 구조나 컴파일러 등에서 n 항 트리를 사용한다.&lt;/p&gt;</description>
      <category>알고리즘/알고리즘 공부</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/68</guid>
      <comments>https://haram17-devlog.tistory.com/68#entry68comment</comments>
      <pubDate>Wed, 15 Feb 2023 18:49:42 +0900</pubDate>
    </item>
    <item>
      <title>[2. 트리, 힙, 그래프] 이진 검색 트리(Binary Search Tree)</title>
      <link>https://haram17-devlog.tistory.com/67</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;이진 검색 트리 (Binary Search Tree)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이진 검색 트리는 다음과 같은 속성을 갖는 이진 트리이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 부모 노드의 값 &amp;gt;= 왼쪽 자식 노드의 값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 부모 노드의 값 &amp;lt;= 오른쪽 자식 노드의 값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는, 부모 노드보다 작거나 같은 모든 원소는 항상 왼쪽에 있고 부모 노드보다 크거나 같은 원소는 항상 오른쪽에 있게 된다. 따라서 원소 검색을 위해 루트 노드부터 차례대로 값을 비교하는 경우, 각 단계마다 검색 범위가 절반으로 줄어든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BST가 마지막 레벨을 제외한 모든 노드에 두 개의 자식 노드가 있으면 BST의 검색 및 삽입 동작은 O(logN)의 시간복잡도를 갖는다. 이러한 형태의 이진 트리는 완전 이진 트리라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;BST에서 원소 검색&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이진 검색 트리에서 원소를 검색할 때는 이진 검색 트리의 특징을 이용해 검색 범위를 반으로 줄이면서 수행할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPtwkm/btrYTVMpQoe/oeG0hPWHamrwQ6vPSv4xdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPtwkm/btrYTVMpQoe/oeG0hPWHamrwQ6vPSv4xdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPtwkm/btrYTVMpQoe/oeG0hPWHamrwQ6vPSv4xdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPtwkm%2FbtrYTVMpQoe%2FoeG0hPWHamrwQ6vPSv4xdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1036&quot; height=&quot;640&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 같은 BST에서 숫자 7을 검색하기 위해 각 노드에서 어느 하위 노드로 이동할 지 정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;루트 노드 (12)와 7을 비교하면 7이 더 작기 때문에 왼쪽 하위 노드로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 후 10과 7을 또 비교하면 7이 더 작으므로 왼쪽 하위 노드로 이동하고, 이를 반복하여 4와 7을 비교하여 오른쪽 하위 노드로 이동한 후 숫자 7을 찾을 수 있다.&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;BST에 새 원소 삽입&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPtwkm/btrYTVMpQoe/oeG0hPWHamrwQ6vPSv4xdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPtwkm/btrYTVMpQoe/oeG0hPWHamrwQ6vPSv4xdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPtwkm/btrYTVMpQoe/oeG0hPWHamrwQ6vPSv4xdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPtwkm%2FbtrYTVMpQoe%2FoeG0hPWHamrwQ6vPSv4xdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1036&quot; height=&quot;640&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 같이 구성되어 있는 BST에서 숫자 18을 삽입하려면 어떻게 해야 할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 원소를 추가하려면 먼저 원소가 삽입될 위치의 부모 노드를 찾아야 한다. 이는 원소 검색과 비슷한 방식으로 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;12 &amp;lt; 18, 20 &amp;gt; 18, 15 &amp;lt; 18, 17 &amp;lt; 18 이기 때문에&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wEZOc/btrYSqGvf0p/4CsMNYnb8VRlz5K5yFWRak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wEZOc/btrYSqGvf0p/4CsMNYnb8VRlz5K5yFWRak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wEZOc/btrYSqGvf0p/4CsMNYnb8VRlz5K5yFWRak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwEZOc%2FbtrYSqGvf0p%2F4CsMNYnb8VRlz5K5yFWRak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1013&quot; height=&quot;624&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;624&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림처럼 17의 오른쪽 하위노드에 18이 삽입된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;BST에서 원소 삭제하기&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BST에서 원소를 삭제할 때에는 단순히 노드를 삭제하는 것 뿐만 아니라, 노드 삭제 후 전체 트리가 BST 속성을 만족하도록 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서 첫 번째단계로 삭제할 노드를 찾는다. 이후에는 해당 노드의 자식 노드에 따라 수행할 행동이 달라지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) &lt;b&gt;삭제할 노드의 자식 노드가 없는 경우&lt;/b&gt;: 단순히 해당 노드를 삭제하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) &lt;b&gt;삭제할 노드의 자식 노드가 하나인 경우&lt;/b&gt;: 노드 삭제 후, 부모 노드의 포인터가 해당 자식 노드를 가리키도록 조정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) &lt;b&gt;삭제할 노드의 자식 노드가 두 개 있는 경우&lt;/b&gt;: 노드 삭제 후, 현재 노드를 후속 노드로 대체한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 1번과 2번은 크게 복잡하지 않지만, 3번은 추가 작업이 필요하다.&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;그렇기 때문에, 이 후속노드를 찾기 위해서는 서브 트리에서 가장 왼쪽에 위치한 노드로 이동하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r7k92/btrZqzQriDK/DhS9vDOrkbQKaVy13HgwCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r7k92/btrZqzQriDK/DhS9vDOrkbQKaVy13HgwCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r7k92/btrZqzQriDK/DhS9vDOrkbQKaVy13HgwCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr7k92%2FbtrZqzQriDK%2FDhS9vDOrkbQKaVy13HgwCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;890&quot; height=&quot;649&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 BST에서 12를 삭제하고 싶을 때, 앞에 설명한 대로 노드 삭제 후, 현재 노드를 후속 노드로 대체하는 작업이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러기 위해서는 먼저 '&lt;b&gt;후속 노드&lt;/b&gt;'를 찾아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후속 노드는 현재 노드(12) 보다 큰 값을 가진 노드 중 가장 작은 값을 가진 노드를 의마하기 때문에 12의 오른쪽 서브 트리에서 가장 왼쪽에 위치한 노드를 찾으면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 BST에서 후속 노드는 15가 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후에는, 후속 노드 값을 루트 노드에 복사한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZ6hRT/btrZrekHXXq/4gxukUoClDmAjLvEjKRj20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZ6hRT/btrZrekHXXq/4gxukUoClDmAjLvEjKRj20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZ6hRT/btrZrekHXXq/4gxukUoClDmAjLvEjKRj20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZ6hRT%2FbtrZrekHXXq%2F4gxukUoClDmAjLvEjKRj20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;846&quot; height=&quot;606&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;/figure&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;이 때, 후속 노드는 항상 오른쪽 자식 노드만 갖게 될 것이다. 만약 왼쪽 노드에 값이 존재했다면, 해당 후속 노드보다 작은 값이 서브 트리에 존재했다는 의미이므로 후속 노드가 올바르지 않다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 결국 해당 후속 노드까지 삭제하면,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;523&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4QrEa/btrZrYhmjbQ/lagNRlHfEcQtFoIyaVOxk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4QrEa/btrZrYhmjbQ/lagNRlHfEcQtFoIyaVOxk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4QrEa/btrZrYhmjbQ/lagNRlHfEcQtFoIyaVOxk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4QrEa%2FbtrZrYhmjbQ%2FlagNRlHfEcQtFoIyaVOxk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;905&quot; height=&quot;523&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;523&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 같이 12가 삭제된 BST가 될 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;시간 복잡도&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리 연산의 시간복잡도는 이론적으로는 매번 검색 범위가 반 씩 줄어들기 때문에 $ O(logN) $ 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나, BST는 트리의 모양이 삽입 순서에 따라 달라진다는 점, 검색 범위가 항상 n/2씩 줄어든다는 것도 보장할 수 없기 때문에 시간 복잡도 $ O(logN) $이 항상 정확하다고 볼 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;균형 트리에서 조금 더 정확하게 시간 복잡도를 계산하는 방법을 다뤄보려 한다.&lt;/p&gt;</description>
      <category>알고리즘/알고리즘 공부</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/67</guid>
      <comments>https://haram17-devlog.tistory.com/67#entry67comment</comments>
      <pubDate>Wed, 15 Feb 2023 16:55:28 +0900</pubDate>
    </item>
    <item>
      <title>[펄어비스 x 경희 소융] 프로젝트 회고</title>
      <link>https://haram17-devlog.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;한 학기 동안 공들여서 진행한 프로젝트가 드디어 최종 발표로 끝을 냈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10/20 에 첫 주제 발표를 시작으로 2/2에 최종 발표를 마쳤으니까 대략.. 3달 반 정도 되지 않을까 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 참가한 프로그램은 펄어비스와 경희대학교 소프트웨어융합학과에서 진행하는 펄어비스 인재양성 프로그램이다.&amp;nbsp;&lt;/p&gt;
&lt;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;나는 전에 소융 수업인 게임 PX 디자인 수업을 들었었고, 해당 수업에서 언리얼에 대해 배울 수 있었기 때문에 언리얼 엔진에 큰 거부감은 없었다. 하지만 언리얼에 익숙치 않다면 프로젝트 시작 전에 언리얼 튜토리얼이라도 공부하는 것을 추천한다..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 다음학기에 또 이런 기회가 열린다면 참가할 마음이 있는 사람들에게 전하고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 무조건 해보세요&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;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;내 주제는 Combustion Simulation for Buildings 였다.&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;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;주제 선정&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주제 정할 때부터 엄청 고민을 많이 했는데, 나는 two minute papers라는 유튜브 채널에서 흥미로운 주제를 찾아서 이를 다르게 적용시켜보는 식으로 주제를 정했다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckuO9S/btrYhbJDu14/pPn0mhFHqwyq7vVFVQSLT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckuO9S/btrYhbJDu14/pPn0mhFHqwyq7vVFVQSLT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckuO9S/btrYhbJDu14/pPn0mhFHqwyq7vVFVQSLT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckuO9S%2FbtrYhbJDu14%2FpPn0mhFHqwyq7vVFVQSLT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;697&quot; height=&quot;683&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;/figure&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;프로젝트 진행&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트는 약 3단계 정도로 개발을 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Heat Transfer - Biological &amp;amp; Physical Attributes - Fire Simulation&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의 단계로 진행되었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 가장 공들였던 Heat Transfer에 대해서 간단하게 말하려고 한다.&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;b&gt;이게 정말 열이 잘 전달되어 불이 퍼지는가&lt;/b&gt;' 였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 대충 퍼지게 불 피워놓고 '건물에서 불이 퍼지는 모습을 구현하였습니다.' 는 부족했다. 이를 시각화하는 무언가가 필요했고, 나는 Vertex Color를 이용하여 각 버텍스들에게 열이 어떤 속도로 전달되고 있고, 발화점에 도달했는지, 언제쯤 발화점에 도달할 지 등에 대해 시각화하는 과정을 추가하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서는 버텍스 관련 문서들도 많고 전에 인턴할 때 몇 번 다뤄봤었기 때문에 언리얼도 비슷하겠지~ 하고 일단 뛰어들었다.&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;겨우 찾아서 와 됐다!! 하면 다른 기능이 안되고.. 또 그게 되면 이게 안되고..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐 알지도 못하는 상태에서 시작하니까 Vertex, Vertex Instance 에서 아주 애를 먹었고 이게 해결되니까 Vertex Color에서, 그 다음은 Vertex Position에서 끊임없이 막혔다. 진짜 산 넘어 산이었다. ㅋㅋㅋㅋ ㅜㅜ&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;&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;이쯤에서 IDE 영업 하나 하자면..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Jetbrains의 Rider&quot; 진짜 갓 IDE 내가 써본것들 중 최고다. (물론 써본거라곤 VS, VSCode가 전부다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jetbrains는 Pycharm, IntelliJ로 유명한데, 나는 Unreal / Unity 와 호환이 되는 Rider를 사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.jetbrains.com/rider/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.jetbrains.com/rider/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675669200670&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Rider: The Cross-Platform .NET IDE from JetBrains&quot; data-og-description=&quot;Develop .NET, ASP.NET, .NET Core, Xamarin or Unity applications on Windows, Mac, Linux&quot; data-og-host=&quot;www.jetbrains.com&quot; data-og-source-url=&quot;https://www.jetbrains.com/rider/&quot; data-og-url=&quot;https://www.jetbrains.com/rider/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qORJq/hyRwC7h2nP/tNlVPxw8PZ2ZgxgNO5KZC1/img.png?width=1281&amp;amp;height=800&amp;amp;face=0_0_1281_800,https://scrap.kakaocdn.net/dn/bgeZDM/hyRwBUQQ9G/dcOr4oPGBFiaZCTri6UrHK/img.png?width=1000&amp;amp;height=500&amp;amp;face=0_0_1000_500,https://scrap.kakaocdn.net/dn/btKXx0/hyRwBUQReN/ReQPgmQ4iCHK4mHBVUFDxK/img.png?width=1000&amp;amp;height=500&amp;amp;face=0_0_1000_500&quot;&gt;&lt;a href=&quot;https://www.jetbrains.com/rider/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.jetbrains.com/rider/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qORJq/hyRwC7h2nP/tNlVPxw8PZ2ZgxgNO5KZC1/img.png?width=1281&amp;amp;height=800&amp;amp;face=0_0_1281_800,https://scrap.kakaocdn.net/dn/bgeZDM/hyRwBUQQ9G/dcOr4oPGBFiaZCTri6UrHK/img.png?width=1000&amp;amp;height=500&amp;amp;face=0_0_1000_500,https://scrap.kakaocdn.net/dn/btKXx0/hyRwBUQReN/ReQPgmQ4iCHK4mHBVUFDxK/img.png?width=1000&amp;amp;height=500&amp;amp;face=0_0_1000_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Rider: The Cross-Platform .NET IDE from JetBrains&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Develop .NET, ASP.NET, .NET Core, Xamarin or Unity applications on Windows, Mac, Linux&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.jetbrains.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 진짜 엄청 편하다. 기존 코드 뜯어보기도 편하고, 디버그 / 빌드 툴도 엄청 잘 되어 있고, Git 버전 관리도 굉장히 편하게 할 수 있다. (머지 툴 최고) 로컬 히스토리도 확인할 수 있고 클래스, 함수 document 작성도 굉장히 편리하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 Unreal Engine 코드 뜯어볼 때가 가장 편했다. 원하는 함수, 변수, 클래스 명 등을 검색하거나 Usage 찾는 과정이 엄청 편하고 손쉽게 가능했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rider로 Jetbrains의 ide에 입문한 나는 .. 이제 모든 IDE를 다 바꾸기 시작했다.. C++/C는 CLion, Python은 Pycharm 등을 사용하고 있는데 만족도 200%다. 대학생은 무료니까 아직 인생 IDE를 찾지 못했다면 한번 고려해보는 것도 좋을 것 같다!&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;결국 엔진 코드에서 vertex color, position, index 등등이 어떤 식으로 구성되어 있는 지를 확인했고, 여러 시행착오 끝에 하나하나씩 해결할 수 있었다.&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;프로젝트 결과물&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2/2에 프로젝트 최종 발표를 진행했다.&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;발표에는 3분 내외의 최종 영상과 5분의 ppt 발표를 준비했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/T9BOY/btrYj2kZOJs/KbUwVYW6s2mxqtvjVTUJeK/Combustion%20Simulation%20for%20Buildings_7_%EC%B5%9C%EC%A2%85%EB%B0%9C%ED%91%9C.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;Combustion Simulation for Buildings_7_최종발표.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.71MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 pdf를 발표자료로 사용하였고, 최종 영상은 교수님 유튜브에 올라와있다. 구경하세요~~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7byZo9cqBuI&quot;&gt;https://www.youtube.com/watch?v=7byZo9cqBuI&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=7byZo9cqBuI&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/xbPZi/hyRwFiGroN/LkbPzKla4xVzuSWUJAiCQK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/7byZo9cqBuI&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;459&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csZctW/btrYcg6bT2P/yvcLf6j4eU2pKh9JrXsydK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csZctW/btrYcg6bT2P/yvcLf6j4eU2pKh9JrXsydK/img.png&quot; data-alt=&quot;교수님 유튜브 메인 영상으로 올라왔다!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csZctW/btrYcg6bT2P/yvcLf6j4eU2pKh9JrXsydK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsZctW%2FbtrYcg6bT2P%2FyvcLf6j4eU2pKh9JrXsydK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;992&quot; height=&quot;459&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;459&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;교수님 유튜브 메인 영상으로 올라왔다!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;후기&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 어려웠다. 처음 해보는 게 너무 많았고 모르는 것도 많아 애초에 시작을 어디서부터 해야할지도 감이 안잡혔다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학기 중이었기에 다른 학교 공부/과제랑도 겹쳐 머릿속에서 할 일들이 뒤죽박죽 섞여있었다. 특히 발표 3 ~ 4일전에는 그냥 집에 박혀서 프로젝트만 했다. 인스타 스토리에서도 적었다시피 구조짜고 알고리즘 짜고.. 꿈에서도 코딩하고.. 나도 모르게 부담감을 갖고 진행한 것 같기도 하다. 물론 그 부담감은 잘하고 싶어서 그런거겠지만.. ㅎㅎ&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;</description>
      <category>프로젝트 회고</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/66</guid>
      <comments>https://haram17-devlog.tistory.com/66#entry66comment</comments>
      <pubDate>Mon, 6 Feb 2023 17:30:07 +0900</pubDate>
    </item>
    <item>
      <title>[Computer Vision] 2. Camera, Geometry and Photometry</title>
      <link>https://haram17-devlog.tistory.com/64</link>
      <description>&lt;h1&gt;Camera&lt;/h1&gt;
&lt;h3&gt;1. Camera Array&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBm0Qi/btrX3qN3VWE/rRciZeDJBZcUI6biRKEsbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBm0Qi/btrX3qN3VWE/rRciZeDJBZcUI6biRKEsbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBm0Qi/btrX3qN3VWE/rRciZeDJBZcUI6biRKEsbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBm0Qi%2FbtrX3qN3VWE%2FrRciZeDJBZcUI6biRKEsbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;366&quot; height=&quot;374&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;카메라 여러대를 이용해서 3D Mesh Model을 얻는 기술이다.&lt;/p&gt;
&lt;p&gt;Static Objec는 카메라 한대로도 가능하다.&lt;/p&gt;
&lt;h3&gt;2. Lens Array (Integral Imaging)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 1.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ELmH5/btrX6in0xMg/f2URcJghUwcm9CYbkRkuV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ELmH5/btrX6in0xMg/f2URcJghUwcm9CYbkRkuV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ELmH5/btrX6in0xMg/f2URcJghUwcm9CYbkRkuV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FELmH5%2FbtrX6in0xMg%2Ff2URcJghUwcm9CYbkRkuV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;731&quot; height=&quot;338&quot; data-filename=&quot;Untitled 1.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;여러 시점의 렌즈를 통해 3D 모델을 얻는 기술이다.&lt;/p&gt;
&lt;p&gt;이를 위해서는 모두 같은 동률의 렌즈가 필요한데, 비싸다.&lt;/p&gt;
&lt;p&gt;카메라 모듈 하나에 약 1000원 정도인데, 렌즈를 15개를 넣으면 15000원.. &lt;/p&gt;
&lt;p&gt;사업성이 충분하지 않다.&lt;/p&gt;
&lt;h3&gt;3. Digital Holography (CGH)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 2.png&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A5bRH/btrX4mYJRiR/y86awg9wX3Kz9skZZcZvxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A5bRH/btrX4mYJRiR/y86awg9wX3Kz9skZZcZvxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A5bRH/btrX4mYJRiR/y86awg9wX3Kz9skZZcZvxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA5bRH%2FbtrX4mYJRiR%2Fy86awg9wX3Kz9skZZcZvxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;734&quot; height=&quot;351&quot; data-filename=&quot;Untitled 2.png&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;레이저를 이용해서 사물의 &lt;strong&gt;Absolute Depth&lt;/strong&gt;를 파악하여 3D 모델을 얻는 기술이다.&lt;/p&gt;
&lt;p&gt;Hologram Mark&lt;/p&gt;
&lt;p&gt;다른 건 3D 모델을 2D 화면으로 3D 모델을 가져오는 기술이었는데, 이거는 3D 모델을 3D 환경에서 볼 수 있다.(3D 데이터의 현실감 상승, 시점을 이동하면 내가 보는 영상도 변함)&lt;/p&gt;
&lt;h3&gt;4. Normal Sensor (Photon-X)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 3.png&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/twAdk/btrX2YxxkF2/hMPwYktioPThqwl2IikfC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/twAdk/btrX2YxxkF2/hMPwYktioPThqwl2IikfC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/twAdk/btrX2YxxkF2/hMPwYktioPThqwl2IikfC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtwAdk%2FbtrX2YxxkF2%2FhMPwYktioPThqwl2IikfC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;695&quot; height=&quot;290&quot; data-filename=&quot;Untitled 3.png&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;사물의 &lt;strong&gt;Relative Depth&lt;/strong&gt;를 파악하여 3D 모델을 얻는 기술이다.&lt;/p&gt;
&lt;p&gt;빛의 회전 감도에 따라 Relative 거리를 측정할 수 있다. (빛이 다시 돌아오면서 회전한다.)&lt;/p&gt;
&lt;h3&gt;5. Structured Light (Stereo Reconstruction)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 4.png&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;278&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r2H6i/btrX327iUqC/HMzR5BgZaHQ3FLnUGzeIGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r2H6i/btrX327iUqC/HMzR5BgZaHQ3FLnUGzeIGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r2H6i/btrX327iUqC/HMzR5BgZaHQ3FLnUGzeIGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr2H6i%2FbtrX327iUqC%2FHMzR5BgZaHQ3FLnUGzeIGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;403&quot; height=&quot;278&quot; data-filename=&quot;Untitled 4.png&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;278&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;pattern Tracking&lt;/p&gt;
&lt;p&gt;특정 패턴을 가진 빛을 쏴서 해당 패턴이 맞춰지는 조건으로 3D 모델을 맞춘다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Accuracy와 Precision의 차이점&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Accuracy: 정확도 (Truth)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Precision: 정밀도 (항상 같은 값)&lt;/p&gt;
&lt;h2&gt;카메라는 Accuracy가 낮다&lt;/h2&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6. Kinect V1&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 5.png&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;356&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R4sbn/btrX2ZXxK9Y/JFKUghXaKnvvJBgijfV6E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R4sbn/btrX2ZXxK9Y/JFKUghXaKnvvJBgijfV6E0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R4sbn/btrX2ZXxK9Y/JFKUghXaKnvvJBgijfV6E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR4sbn%2FbtrX2ZXxK9Y%2FJFKUghXaKnvvJBgijfV6E0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;671&quot; height=&quot;356&quot; data-filename=&quot;Untitled 5.png&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;356&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;직진성을 가진 레이저 빛을 물체에 쏴서 빛이 도착하는 시간을 계산하여 3D data를 얻는다.&lt;/p&gt;
&lt;p&gt;time of flight&lt;/p&gt;
&lt;h3&gt;7. Time of Flight&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 6.png&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2EgIf/btrX4jVaSXB/b5BGbJzsLrKP5k4vusaBgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2EgIf/btrX4jVaSXB/b5BGbJzsLrKP5k4vusaBgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2EgIf/btrX4jVaSXB/b5BGbJzsLrKP5k4vusaBgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2EgIf%2FbtrX4jVaSXB%2Fb5BGbJzsLrKP5k4vusaBgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;665&quot; height=&quot;407&quot; data-filename=&quot;Untitled 6.png&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;Kinect V1은 Time of Flight 사용한다.&lt;/p&gt;
&lt;p&gt;빛이 도착하는 시간으로 distance 계산한다.&lt;/p&gt;
&lt;p&gt;실제로는 빛을 기다리지 않고 빛의 위상차를 이용한다. (근적외선 파장의 빛)&lt;/p&gt;
&lt;p&gt;active sensor: &lt;/p&gt;
&lt;p&gt;ex. RIDAR&lt;/p&gt;
&lt;h3&gt;8. Laser Scanning&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 7.png&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5KM6U/btrX8igUGr8/O0N8v53UUgdrADzLiU547K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5KM6U/btrX8igUGr8/O0N8v53UUgdrADzLiU547K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5KM6U/btrX8igUGr8/O0N8v53UUgdrADzLiU547K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5KM6U%2FbtrX8igUGr8%2FO0N8v53UUgdrADzLiU547K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;412&quot; data-filename=&quot;Untitled 7.png&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;h1&gt;Color Camera&lt;/h1&gt;
&lt;h3&gt;Digital Image&lt;/h3&gt;
&lt;p&gt;3D로 펼쳐진 세상을 2D의 Digital Image로 변환시킬 때, 눈으로 보는 것과 카메라로 찍은 Image의 차이를 생각해보자.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;3D Data가 사라지게 된다.&lt;/li&gt;
&lt;li&gt;눈으로 느낄 수 있는 질감을 카메라의 픽셀로 표현할 수 없다.&lt;/li&gt;
&lt;li&gt;공간 Quantization 으로 인한 이미지 Blur가 생긴다.&lt;/li&gt;
&lt;li&gt;영상일 경우 시간 Quantization 으로 인해 frame 사이의 loss가 생긴다.&lt;/li&gt;
&lt;li&gt;Color 표현 능력이 줄어든다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이러한 문제점을 해결해야 3D 데이터를 2D image로 완벽히 구현할 수 있을 것이다.&lt;/p&gt;
&lt;h3&gt;Image Formation&lt;/h3&gt;
&lt;p&gt;카메라는 3D를 2D로 Projection하는 것과 같다.&lt;/p&gt;
&lt;p&gt;카메라의 원리를 생각해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 9.png&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx8xUG/btrX40HQ8oH/PRf6ngRKvwXOTNzCj2H7Y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx8xUG/btrX40HQ8oH/PRf6ngRKvwXOTNzCj2H7Y1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx8xUG/btrX40HQ8oH/PRf6ngRKvwXOTNzCj2H7Y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx8xUG%2FbtrX40HQ8oH%2FPRf6ngRKvwXOTNzCj2H7Y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;240&quot; data-filename=&quot;Untitled 9.png&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;240&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;왼쪽과 같은 Object가 있다고 생각했을 때, 모든 빛을 받는 단순한 Film 센서가 있다고 생각해보자.&lt;/p&gt;
&lt;p&gt;이 센서에는 모든 빛이 다 들어오기 때문에 물체의 상이 맺히지 않게 된다.&lt;/p&gt;
&lt;p&gt;즉, 렌즈로서의 역할을 수행할 수 없다는 뜻이다. (카메라의 기능을 수행하지 못한다.)&lt;/p&gt;
&lt;h3&gt;Pinhole Camera&lt;/h3&gt;
&lt;p&gt;그래서 나타난 카메라가 Pinhole Camera이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 8.png&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1TBGS/btrX311C06F/fbKkIZBpU4eFUGs0iMcmn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1TBGS/btrX311C06F/fbKkIZBpU4eFUGs0iMcmn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1TBGS/btrX311C06F/fbKkIZBpU4eFUGs0iMcmn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1TBGS%2FbtrX311C06F%2FfbKkIZBpU4eFUGs0iMcmn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;486&quot; height=&quot;206&quot; data-filename=&quot;Untitled 8.png&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;아까의 Object-Film 구조에서 중간에 구멍이 뚫린 장애물을 하나 놓는다.&lt;/p&gt;
&lt;p&gt;그럼, 한 곳에서 반사되는 여러 방향의 빛 중 해당 구멍으로 지나가는 빛만 Film에 도달한다.&lt;/p&gt;
&lt;p&gt;이를 이용하면 앞서 나왔던 여러 빛에 의한 Blurring 현상을 사라지게 만들 수 있게 된다.&lt;/p&gt;
&lt;p&gt;그러나, 이 방식을 사용하게 되면 Film에 들어오는 빛의 양 자체가 적어지게 된다. 그럼 밝기 자체가 낮아져서 물체를 명확하게 볼 수 없게 된다.&lt;/p&gt;
&lt;p&gt;구멍 주변에 아주 살짝 막히는 빛들 조차 차단되기 때문에, 구멍 앞에 렌즈를 붙여서 빛을 모아주는 역할을 하게 된다.&lt;/p&gt;
&lt;p&gt;아래 그림을 보면 더 쉽게 이해할 수 있을 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 10.png&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;446&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k4A58/btrX6oBJlcS/IaeRvK7HlIGVifbq8FQQk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k4A58/btrX6oBJlcS/IaeRvK7HlIGVifbq8FQQk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k4A58/btrX6oBJlcS/IaeRvK7HlIGVifbq8FQQk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk4A58%2FbtrX6oBJlcS%2FIaeRvK7HlIGVifbq8FQQk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;734&quot; height=&quot;446&quot; data-filename=&quot;Untitled 10.png&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;446&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;당연하게도, pinhole의 구멍이 커질수록 film에 들어가는 빛의 양은 많아지므로 밝기가 커지지만, Blurring 현상도 생기게 된다.&lt;/p&gt;
&lt;p&gt;밝기는 밝아지고, Blurring 현상도 막기 위해 앞서 설명한 것처럼 구멍 앞에 렌즈를 부착하게 되고, 이 렌즈 크기에 따라 화질 또한 커지게 된다.&lt;/p&gt;
&lt;h3&gt;Camera obscura&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 11.png&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FmR0j/btrX2p3eyto/Z74S7IodDNGMOy3rtItJ71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FmR0j/btrX2p3eyto/Z74S7IodDNGMOy3rtItJ71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FmR0j/btrX2p3eyto/Z74S7IodDNGMOy3rtItJ71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFmR0j%2FbtrX2p3eyto%2FZ74S7IodDNGMOy3rtItJ71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;777&quot; height=&quot;347&quot; data-filename=&quot;Untitled 11.png&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 12.png&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eFHLGZ/btrX8iusENh/tne5LXeMuy43P9MPOFrdA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eFHLGZ/btrX8iusENh/tne5LXeMuy43P9MPOFrdA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eFHLGZ/btrX8iusENh/tne5LXeMuy43P9MPOFrdA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeFHLGZ%2FbtrX8iusENh%2Ftne5LXeMuy43P9MPOFrdA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;376&quot; data-filename=&quot;Untitled 12.png&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;앞서 설명한 Pinhole Camera의 방식을 이용해 많은 화가들이 그림을 그렸다고 한다.&lt;/p&gt;
&lt;h2&gt;Projective Geometry&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 13.png&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVAnqf/btrX4mYJRAq/xh9WmGZyxK3OeJYmSycPx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVAnqf/btrX4mYJRAq/xh9WmGZyxK3OeJYmSycPx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVAnqf/btrX4mYJRAq/xh9WmGZyxK3OeJYmSycPx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVAnqf%2FbtrX4mYJRAq%2Fxh9WmGZyxK3OeJYmSycPx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;372&quot; data-filename=&quot;Untitled 13.png&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 14.png&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BiWge/btrX3qAvZw1/4IZum6rnvV2AJ2jcmskMI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BiWge/btrX3qAvZw1/4IZum6rnvV2AJ2jcmskMI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BiWge/btrX3qAvZw1/4IZum6rnvV2AJ2jcmskMI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBiWge%2FbtrX3qAvZw1%2F4IZum6rnvV2AJ2jcmskMI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;505&quot; height=&quot;352&quot; data-filename=&quot;Untitled 14.png&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;위 두 사진을 보면, 3D의 물체를 2D image로 projection 시켰을 때 Length정보와 Angles 정보가 명확하지 않고 사라지는 것을 느낄 수 있다.&lt;/p&gt;
&lt;p&gt;그 대신, Straight Line 직선은 여전히 직선이다. (Shape은 유지되지 않는다.)&lt;/p&gt;
&lt;p&gt;이 직선 정보로 3D data를 얻어낼 수 있다.&lt;/p&gt;
&lt;h2&gt;Vanishing points and lines&lt;/h2&gt;
&lt;p&gt;소실점에 대해서 들어봤을 것이다.&lt;/p&gt;
&lt;p&gt;평행한 직선은 원근법에 의해 image 상에서 소실점이 생긴다. &lt;/p&gt;
&lt;p&gt;한 image 내에서 소실점이 생기는 부분들을 연결했을 때 Vanishing Line이 생기게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 15.png&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bK2vpo/btrX1Pagj8o/SGKqTT4mjJ6LUFdJpr8NBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bK2vpo/btrX1Pagj8o/SGKqTT4mjJ6LUFdJpr8NBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bK2vpo/btrX1Pagj8o/SGKqTT4mjJ6LUFdJpr8NBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbK2vpo%2FbtrX1Pagj8o%2FSGKqTT4mjJ6LUFdJpr8NBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;798&quot; height=&quot;480&quot; data-filename=&quot;Untitled 15.png&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;위 그림처럼 왼쪽의 평행한 선들이 모여 왼쪽 Vanishing Point을 만들고, 오른쪽 벽의 선들이 모여 오른쪽에 Vanishing point를 만들게 된다. &lt;/p&gt;
&lt;p&gt;이 두 Vanishing point를 연결하여 Vanishing Line을 만들게 된다.&lt;/p&gt;
&lt;p&gt;이 때, Vertical로 사진을 보게되면 2차원에서 평행한 것을 알 수 있다. 2차원에서 평행한 선들은 3차원에서도 평행하게 된다.&lt;/p&gt;
&lt;p&gt;사람들이 만든 것들은 평행하고 대칭적인 것이 많은데, 이를 이용해 후에 2D Image를 3D Data로 표현할 수 있게 된다.&lt;/p&gt;
&lt;h2&gt;Image Geometry&lt;/h2&gt;
&lt;p&gt;Image의 물체에서 3D 위치 데이터를 얻는 개념에 대해 생각해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 16.png&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;297&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzqW2V/btrX3sLWEID/QmTK8mdUSthfWyqNCiSsB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzqW2V/btrX3sLWEID/QmTK8mdUSthfWyqNCiSsB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzqW2V/btrX3sLWEID/QmTK8mdUSthfWyqNCiSsB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzqW2V%2FbtrX3sLWEID%2FQmTK8mdUSthfWyqNCiSsB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;297&quot; data-filename=&quot;Untitled 16.png&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;297&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;위 그림은 물체가 실제 세상에서 World Coordinate System으로 나타낸 그림이다.&lt;/p&gt;
&lt;p&gt;이 때 원점(origin)은 정해져있지 않다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 17.png&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btr4Gt/btrX3uwdrxR/pj1hd53bVRKCL1vEo41FAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btr4Gt/btrX3uwdrxR/pj1hd53bVRKCL1vEo41FAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btr4Gt/btrX3uwdrxR/pj1hd53bVRKCL1vEo41FAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbtr4Gt%2FbtrX3uwdrxR%2Fpj1hd53bVRKCL1vEo41FAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;716&quot; height=&quot;369&quot; data-filename=&quot;Untitled 17.png&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;위 그림은 물체의 카메라 상으로 Camera Coordinate System을 나타낸 모습이다.&lt;/p&gt;
&lt;p&gt;Z 축은 Optic Axis, 즉 빛이 투과하는 광로를 나타낸다.&lt;/p&gt;
&lt;p&gt;원점은 렌즈의 중심이 될 수 있다.&lt;/p&gt;
&lt;p&gt;결국, Image의 기하학 정보를 알아내는 것의 처음은, World Coordinate 정보를 Camera Coordinate 정보로 변환하고, 이를 통해 Image Coordinate정보를 알아내 Pixel Coordinate로 변환하는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 18.png&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLy18G/btrX1OPXl1m/Nzrko3PyshpkoDbbBYzA01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLy18G/btrX1OPXl1m/Nzrko3PyshpkoDbbBYzA01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLy18G/btrX1OPXl1m/Nzrko3PyshpkoDbbBYzA01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLy18G%2FbtrX1OPXl1m%2FNzrko3PyshpkoDbbBYzA01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;336&quot; data-filename=&quot;Untitled 18.png&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;h3&gt;Image Photometry&lt;/h3&gt;
&lt;p&gt;이미지의 3D Color 정보를 얻을 수 있는 방식에 대해 생각해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 19.png&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ehTuC0/btrX6nCNVTQ/d5l7ZdLek7pVv7obRask1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ehTuC0/btrX6nCNVTQ/d5l7ZdLek7pVv7obRask1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ehTuC0/btrX6nCNVTQ/d5l7ZdLek7pVv7obRask1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FehTuC0%2FbtrX6nCNVTQ%2Fd5l7ZdLek7pVv7obRask1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;771&quot; height=&quot;497&quot; data-filename=&quot;Untitled 19.png&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;광원에서 광자를 방출하게 되면, Photon은 물체에 닿아 우리 눈으로 들어오게 된다.&lt;/p&gt;
&lt;p&gt;이때, 빛의 Spectrum별로 빛의 반사량이 다르고, 빛이 선택적으로 반사되기 때문에 같은 물체여도 부분적으로 다르게 보이게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 20.png&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;485&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMNZgW/btrX32TJCsS/4q78kHjYyeDeOxBr35Nms1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMNZgW/btrX32TJCsS/4q78kHjYyeDeOxBr35Nms1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMNZgW/btrX32TJCsS/4q78kHjYyeDeOxBr35Nms1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMNZgW%2FbtrX32TJCsS%2F4q78kHjYyeDeOxBr35Nms1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;741&quot; height=&quot;485&quot; data-filename=&quot;Untitled 20.png&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;485&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;Irradiance는 단위 면적 Surface가 받는 Radiant Flux, Radiance는 한 지점에서 특정 한 방향으로 내보내는 복사량정도로 대충 정리할 수 있을 것 같다.&lt;/p&gt;
&lt;p&gt;Incoming Light에 Outgoing Light가 대략 하나씩 매칭이 된다면 거울이 될테고, 모든 곳으로 퍼지게 되면 일반 벽처럼 느끼게 될 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 21.png&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsg5f7/btrX2XrP6iM/CIEj2BfgU3sLVeUXh4LR40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsg5f7/btrX2XrP6iM/CIEj2BfgU3sLVeUXh4LR40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsg5f7/btrX2XrP6iM/CIEj2BfgU3sLVeUXh4LR40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbsg5f7%2FbtrX2XrP6iM%2FCIEj2BfgU3sLVeUXh4LR40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;440&quot; data-filename=&quot;Untitled 21.png&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;위 그림은 각 물체 자체가 나타내는 파장에 대한 정보이다.&lt;/p&gt;
&lt;p&gt;여기서 Albedo라는 개념이 나오는데, 이는 물질 자체가 어떤 파장의 빛을 반사하는 지에 대한 정보라고 말할 수 있다.&lt;/p&gt;
&lt;p&gt;결국 해당 물질에서 반사되는 빛을 감지하여 색상 정보를 얻을 수 있는 방법은 아래 그림과 식을 이용하게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 22.png&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uCSAd/btrX4ZoF9BD/h0nghraK7iGC8BlbIEdzRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uCSAd/btrX4ZoF9BD/h0nghraK7iGC8BlbIEdzRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uCSAd/btrX4ZoF9BD/h0nghraK7iGC8BlbIEdzRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuCSAd%2FbtrX4ZoF9BD%2Fh0nghraK7iGC8BlbIEdzRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;692&quot; height=&quot;468&quot; data-filename=&quot;Untitled 22.png&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Computer Vision</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/64</guid>
      <comments>https://haram17-devlog.tistory.com/64#entry64comment</comments>
      <pubDate>Sat, 4 Feb 2023 15:34:30 +0900</pubDate>
    </item>
    <item>
      <title>[2. 트리, 힙, 그래프] 트리</title>
      <link>https://haram17-devlog.tistory.com/61</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;선형 자료 구조로 표현할 수 없는 대표적인 문제로 계층적 문제(hierarchical problem)와 순환 종속성(cyclic dependency) 문제가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사의 조직도, 대학의 교과 과정 계층도 등은 계층적으로 데이터를 표현해야 한다. 이 때 사용하는 자료 구조는 트리 (tree)이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFmzW1/btrWCyNKXtb/i6JhOUjpwlkNsiwdlvqoj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFmzW1/btrWCyNKXtb/i6JhOUjpwlkNsiwdlvqoj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFmzW1/btrWCyNKXtb/i6JhOUjpwlkNsiwdlvqoj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFmzW1%2FbtrWCyNKXtb%2Fi6JhOUjpwlkNsiwdlvqoj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;271&quot; height=&quot;297&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림처럼 트리는 계층을 구성한다. 데이터가 저장된 부분은 노드(node)라고 부르고, 노드와 노드 사이를 잇는 선을 edge라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 맨 위에 나타나는 노드를 root node라고 한다.&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;전위 순회 (preorder traversal)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 현재 노드를 먼저 방문하고, 그 다음은 현재 노드의 왼쪽 하위 노드를, 마지막으로는 현재 노드의 오른쪽 하위 노드를 재귀적인 방식으로 방문한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eazUu5/btrWCUCNUhd/ZLV8z03wqkDAB3d8JDlxek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eazUu5/btrWCUCNUhd/ZLV8z03wqkDAB3d8JDlxek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eazUu5/btrWCUCNUhd/ZLV8z03wqkDAB3d8JDlxek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeazUu5%2FbtrWCUCNUhd%2FZLV8z03wqkDAB3d8JDlxek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;242&quot; height=&quot;274&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;preorder 방식을 코드로 구현하면 다음과 같이 구현할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1674041925608&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void preOrder(node* start)
{
    if(!start)
    	return;
    cout &amp;lt;&amp;lt; start-&amp;gt;position &amp;lt;&amp;lt; &quot;, &quot;;
    preOrder(start-&amp;gt;first);
    preOrder(start-&amp;gt;second);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;중위 순회 (in-order traversal)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중위 순회 방법은 왼쪽 노드를 먼저 방문하고, 현재 노드, 오른쪽 노드를 방문한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTKhY1/btrWDbqOcSn/G9y0Fj6SjVU9q2QKpggsf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTKhY1/btrWDbqOcSn/G9y0Fj6SjVU9q2QKpggsf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTKhY1/btrWDbqOcSn/G9y0Fj6SjVU9q2QKpggsf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTKhY1%2FbtrWDbqOcSn%2FG9y0Fj6SjVU9q2QKpggsf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;267&quot; height=&quot;301&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;in-order 방식을 코드로 구현하면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1674042154724&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void inOrder(node* start)
{
    if(!start)
    	return;
        
    inOrder(start-&amp;gt;first);
    cout &amp;lt;&amp;lt; start-&amp;gt;position &amp;lt;&amp;lt; &quot;, &quot;;
    inOrder(start-&amp;gt;second);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;후위 순회 (post-order traversal)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 두 자식 노드를 먼저 방문한 후, 현재 노드를 방문한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4e29s/btrWCUv1USB/vTJQyTVKpMesdrkyTKwbCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4e29s/btrWCUv1USB/vTJQyTVKpMesdrkyTKwbCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4e29s/btrWCUv1USB/vTJQyTVKpMesdrkyTKwbCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4e29s%2FbtrWCUv1USB%2FvTJQyTVKpMesdrkyTKwbCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;256&quot; height=&quot;306&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;post-order 방식을 코드로 구현하면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1674043117913&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void postOrder(node* start)
{
    if(!start)
    	return;
        
    postOrder(start-&amp;gt;first);
    postOrder(start-&amp;gt;second);
    cout &amp;lt;&amp;lt; start-&amp;gt;position &amp;lt;&amp;lt; &quot;, &quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;레벨 순서 순회 (level order traversal)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리의 맨 위 레벨부터 아래 레벨까지, 왼쪽 노드에서 오른쪽 노드 순서로 방문한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5SFfO/btrWEQ0udZ2/OyVHoAx9fsDF7rlWO08kV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5SFfO/btrWEQ0udZ2/OyVHoAx9fsDF7rlWO08kV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5SFfO/btrWEQ0udZ2/OyVHoAx9fsDF7rlWO08kV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5SFfO%2FbtrWEQ0udZ2%2FOyVHoAx9fsDF7rlWO08kV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;271&quot; height=&quot;300&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레벨 순서 순회는 다음 코드와 같이 작성할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1674043930833&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void levelOrder(node* start){
    if(!start)
        return;

    queue&amp;lt;node*&amp;gt; q;
    q.push(start);

    while (!q.empty()){
        int size = q.size();
        for(int i = 0; i &amp;lt; size; i++){
            auto current = q.front();
            q.pop();

            cout &amp;lt;&amp;lt; current-&amp;gt;position &amp;lt;&amp;lt; &quot;, &quot;;
            if(current-&amp;gt;first)
                q.push(current-&amp;gt;first);
            if(current-&amp;gt;second)
                q.push(current-&amp;gt;second);
        }
        cout &amp;lt;&amp;lt; &quot;\n&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/알고리즘 공부</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/61</guid>
      <comments>https://haram17-devlog.tistory.com/61#entry61comment</comments>
      <pubDate>Wed, 18 Jan 2023 22:41:50 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 - 백준 11053 (가장 긴 증가하는 부분 수열)</title>
      <link>https://haram17-devlog.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;문제 링크: &lt;a href=&quot;https://www.acmicpc.net/problem/11053&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11053&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674036011127&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;11053번: 가장 긴 증가하는 부분 수열&quot; data-og-description=&quot;수열 A가 주어졌을 때, 가장 긴 증가하는&amp;nbsp;부분&amp;nbsp;수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분&amp;nbsp;수열은&amp;nbsp;A = {10, 20, 10, 30, 20, 50} 이&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/11053&quot; data-og-url=&quot;https://www.acmicpc.net/problem/11053&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/csxkAd/hyRkhouKdj/z98C2I7kuqJfYxm0UlGKxk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11053&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/11053&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/csxkAd/hyRkhouKdj/z98C2I7kuqJfYxm0UlGKxk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;11053번: 가장 긴 증가하는 부분 수열&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;수열 A가 주어졌을 때, 가장 긴 증가하는&amp;nbsp;부분&amp;nbsp;수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분&amp;nbsp;수열은&amp;nbsp;A = {10, 20, 10, 30, 20, 50} 이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문제&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수열 A가 주어졌을 때, 가장 긴 증가하는&amp;nbsp;부분&amp;nbsp;수열을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분&amp;nbsp;수열은&amp;nbsp;A = {&lt;b&gt;10&lt;/b&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;20&lt;/b&gt;, 10,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;30&lt;/b&gt;, 20,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;50&lt;/b&gt;} 이고, 길이는 4이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;입력&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째 줄에 수열 A의 크기 N (1 &amp;le; N &amp;le; 1,000)이 주어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 &amp;le; Ai&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 1,000)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;출력&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #555555;&quot;&gt;첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.&lt;/span&gt;&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;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;풀이 및 코드&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 수열에서 가장 긴 증가하는 부분 수열을 구할 수 있는 방법을 표로 나타내면 다음과 같다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;[0]&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;[1]&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;[2]&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;[3]&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;[4]&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;[5]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;20&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;30&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;20&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;2 (10, 20)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;3 (10, 20, 30)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;2 (10, 20)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;4 (10, 20, 30, 50)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 표를 풀어서 쓰면 다음과 같이 쓸 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[0]이 포함되는 부분 수열 중 가장 긴 증가하는 부분 수열은 {10}으로 원소의 개수는 1개이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1]이 포함되는 부분 수열 중 가장 긴 증가하는 부분 수열은 {10, 20}으로 원소의 개수는 2개이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2]이 포함되는 부분 수열 중 가장 긴 증가하는 부분 수열은 {10}으로 원소의 개수는 1개이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 마지막 [5]이 포함되는 부분 수열 중 가장 긴 증가하는 부분 수열은 {10, 20, 30, 50}으로 원소의 개수는 4개이다.&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;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;1) 각 [i] 번째의 원소의 개수를 구하기 위해서는 [0] ~ [i - 1]까지의 원소들 중 [i] 번째의 원소보다 작은 것들을 뽑고, &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;2) 작은 것들 중 가장 큰 원소의 개수에 1을 더한 것과 같다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 말로 풀어 쓴 식을 코드로 표현하면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1674036939076&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int input[1000];
int dp[1000];
int main(){
    int n;
    cin &amp;gt;&amp;gt; n;

    for(int i = 0; i &amp;lt; n; i++){
        cin &amp;gt;&amp;gt; input[i];
    }

    dp[0] = 1;
    int result = 1;
    for(int i = 1; i &amp;lt; n; i++){
        int temp = 0;
        dp[i] = 1;
        for(int j = 0; j &amp;lt; i; j++){
            if(input[i] &amp;gt; input[j]){
                if(temp &amp;lt; dp[j]){
                    temp = dp[j];
                    dp[i] = temp + 1;
                }
            }
        }
        if(result &amp;lt; dp[i])
            result = dp[i];
    }

    cout &amp;lt;&amp;lt; result &amp;lt;&amp;lt; endl;

    return 0;
}&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;a href=&quot;https://github.com/haram1117/AlgorithmStudy/commit/d7649d19c48b70fb9a8ff6bc1fd679dbb6fa2196&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/haram1117/AlgorithmStudy/commit/d7649d19c48b70fb9a8ff6bc1fd679dbb6fa2196&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674036975420&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;DP11053 &amp;middot; haram1117/AlgorithmStudy@d7649d1&quot; data-og-description=&quot;Show file tree Showing 7 changed files with 82 additions and 35 deletions.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/haram1117/AlgorithmStudy/commit/d7649d19c48b70fb9a8ff6bc1fd679dbb6fa2196&quot; data-og-url=&quot;https://github.com/haram1117/AlgorithmStudy/commit/d7649d19c48b70fb9a8ff6bc1fd679dbb6fa2196&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://github.com/haram1117/AlgorithmStudy/commit/d7649d19c48b70fb9a8ff6bc1fd679dbb6fa2196&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/haram1117/AlgorithmStudy/commit/d7649d19c48b70fb9a8ff6bc1fd679dbb6fa2196&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DP11053 &amp;middot; haram1117/AlgorithmStudy@d7649d1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Show file tree Showing 7 changed files with 82 additions and 35 deletions.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>알고리즘/BOJ</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/60</guid>
      <comments>https://haram17-devlog.tistory.com/60#entry60comment</comments>
      <pubDate>Wed, 18 Jan 2023 19:16:35 +0900</pubDate>
    </item>
    <item>
      <title>알고리즘 - 백준 11052 (카드 구매하기)</title>
      <link>https://haram17-devlog.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;문제 링크: &lt;a href=&quot;https://www.acmicpc.net/problem/11052&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11052&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1673953443283&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;11052번: 카드 구매하기&quot; data-og-description=&quot;첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다.&amp;nbsp;(1 &amp;le; N &amp;le; 1,000) 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 &amp;le; Pi &amp;le; 10,000)&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/11052&quot; data-og-url=&quot;https://www.acmicpc.net/problem/11052&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/q57Ir/hyRkugmiMR/Rax45uNOLfiJUgCdKdrXK0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/byHDfJ/hyRknheKAx/i3wBZJ20k44IeD9hefV7IK/img.png?width=600&amp;amp;height=818&amp;amp;face=0_0_600_818,https://scrap.kakaocdn.net/dn/bqs3eM/hyRkpTEQ3c/oNzsAhN4XRGRpKAA6V4K70/img.png?width=600&amp;amp;height=818&amp;amp;face=448_432_477_463&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11052&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/11052&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/q57Ir/hyRkugmiMR/Rax45uNOLfiJUgCdKdrXK0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/byHDfJ/hyRknheKAx/i3wBZJ20k44IeD9hefV7IK/img.png?width=600&amp;amp;height=818&amp;amp;face=0_0_600_818,https://scrap.kakaocdn.net/dn/bqs3eM/hyRkpTEQ3c/oNzsAhN4XRGRpKAA6V4K70/img.png?width=600&amp;amp;height=818&amp;amp;face=448_432_477_463');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;11052번: 카드 구매하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다.&amp;nbsp;(1 &amp;le; N &amp;le; 1,000) 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 &amp;le; Pi &amp;le; 10,000)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문제&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 민규네 동네에서는 스타트링크에서 만든 PS카드를 모으는 것이 유행이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PS카드는 PS(Problem Solving)분야에서 유명한 사람들의 아이디와 얼굴이 적혀있는 카드이다. 각각의 카드에는 등급을 나타내는 색이 칠해져 있고, 다음과 같이 8가지가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;전&lt;/span&gt;설카드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;레드카드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ff8c00;&quot;&gt;오렌지카드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #aa00aa;&quot;&gt;퍼플카드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;블루카드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #03a89e;&quot;&gt;청록카드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #008000;&quot;&gt;그린카드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #808080;&quot;&gt;그레이카드&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카드는 카드팩의 형태로만 구매할 수 있고, 카드팩의 종류는 카드 1개가 포함된 카드팩, 카드 2개가 포함된 카드팩, ... 카드 N개가 포함된 카드팩과 같이 총 N가지가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;민규는 카드의 개수가 적은 팩이더라도 가격이 비싸면 높은 등급의 카드가 많이 들어있을 것이라는 미신을 믿고 있다. 따라서, 민규는 돈을 최대한 많이 지불해서 카드 N개 구매하려고 한다. 카드가 i개 포함된 카드팩의 가격은 Pi원이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 카드팩이 총 4가지 종류가 있고, P1&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 1, P2&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 5, P3&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 6, P4&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 7인 경우에 민규가 카드 4개를 갖기 위해 지불해야 하는 금액의 최댓값은 10원이다. 2개 들어있는 카드팩을 2번 사면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P1&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 5, P2&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 2, P3&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 8, P4&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 10인 경우에는 카드가 1개 들어있는 카드팩을 4번 사면 20원이고, 이 경우가 민규가 지불해야 하는 금액의 최댓값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로, P1&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 3, P2&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 5, P3&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 15, P4&lt;span&gt;&amp;nbsp;&lt;/span&gt;=&amp;nbsp;16인 경우에는 3개 들어있는 카드팩과 1개 들어있는 카드팩을 구매해 18원을 지불하는 것이 최댓값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카드 팩의 가격이 주어졌을 때, N개의 카드를 구매하기 위해 민규가 지불해야 하는 금액의 최댓값을 구하는 프로그램을 작성하시오. N개보다 많은 개수의 카드를 산 다음, 나머지 카드를 버려서 N개를 만드는 것은 불가능하다. 즉, 구매한 카드팩에 포함되어 있는 카드 개수의 합은 N과 같아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;입력&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다.&amp;nbsp;(1 &amp;le; N &amp;le; 1,000)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 &amp;le; Pi&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 10,000)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;출력&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #555555;&quot;&gt;첫째 줄에 민규가 카드 N개를 갖기 위해 지불해야 하는 금액의 최댓값을 출력한다.&lt;/span&gt;&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;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;풀이 및 코드&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 i 별로 카드 i개를 갖기 위해 지불해야 하는 금액의 최댓값을 dp 배열에 저장해놓는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uZ3OD/btrWxs62W7X/6KZx65W5BS4Y401Mk7HJ50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uZ3OD/btrWxs62W7X/6KZx65W5BS4Y401Mk7HJ50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uZ3OD/btrWxs62W7X/6KZx65W5BS4Y401Mk7HJ50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuZ3OD%2FbtrWxs62W7X%2F6KZx65W5BS4Y401Mk7HJ50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1174&quot; height=&quot;180&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 예제에 대해 dp 배열을 작성해보면 다음과 같다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 68px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 17px;&quot; colspan=&quot;2&quot;&gt;max(5, 1+1) = 5&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 17px; width: 75%;&quot; colspan=&quot;3&quot;&gt;max(6, 5 + 1) = 6&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot; colspan=&quot;4&quot;&gt;max(7, 6 + 1, 5 + 5) = 10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P4에 대해서만 설명해보면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4개의 카드가 들어있는 카드 팩 한개 (7)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3개의 카드가 들어있는 카드 팩 한개 + 1개의 카드가 들어있는 카드 팩 한개 (6 + 1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2개의 카드가 들어있는 카드 팩 두개 (5 + 5)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 세 경우 중 가장 큰 최댓값을 구하면 10이 나오게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정을 코드로 나타내면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1673954798469&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int input[1000];
int dp[1000];
int main(){
    int n;
    cin &amp;gt;&amp;gt; n;
    for(int i = 0; i &amp;lt; n; i++){
        cin &amp;gt;&amp;gt; input[i];
    }

    for(int i = 0; i &amp;lt; n; i++){
        dp[i] = input[i];
        for(int j = 0; j &amp;lt; float(i) / 2; j++){
            dp[i] = max(dp[i], dp[j] + dp[i - j - 1]);
        }
    }

    cout &amp;lt;&amp;lt; dp[n - 1] &amp;lt;&amp;lt; endl;

    return 0;
}&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;a href=&quot;https://github.com/haram1117/AlgorithmStudy/commit/f3fb3b7149c700c83b3ff6463032570b8c418d75&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/haram1117/AlgorithmStudy/commit/f3fb3b7149c700c83b3ff6463032570b8c418d75&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1673954838776&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;DP11052 &amp;middot; haram1117/AlgorithmStudy@f3fb3b7&quot; data-og-description=&quot;Show file tree Showing 7 changed files with 64 additions and 34 deletions.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/haram1117/AlgorithmStudy/commit/f3fb3b7149c700c83b3ff6463032570b8c418d75&quot; data-og-url=&quot;https://github.com/haram1117/AlgorithmStudy/commit/f3fb3b7149c700c83b3ff6463032570b8c418d75&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oTnmM/hyRi3SdIzw/D38uGgOrNN5yVKkbFJYvkK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/haram1117/AlgorithmStudy/commit/f3fb3b7149c700c83b3ff6463032570b8c418d75&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/haram1117/AlgorithmStudy/commit/f3fb3b7149c700c83b3ff6463032570b8c418d75&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oTnmM/hyRi3SdIzw/D38uGgOrNN5yVKkbFJYvkK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DP11052 &amp;middot; haram1117/AlgorithmStudy@f3fb3b7&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Show file tree Showing 7 changed files with 64 additions and 34 deletions.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>알고리즘/BOJ</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/59</guid>
      <comments>https://haram17-devlog.tistory.com/59#entry59comment</comments>
      <pubDate>Tue, 17 Jan 2023 20:27:23 +0900</pubDate>
    </item>
    <item>
      <title>[1. 리스트, 스택, 큐] 컨테이너 어댑터</title>
      <link>https://haram17-devlog.tistory.com/58</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;컨테이너 어댑터(container adaptor)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;기존의 컨테이너를 변형하여 꼭 필요한 인터페이스만을 제공하여 만든 컨테이너로, C++에서 제공하는 컨테이너 어댑터는 std::stack, std::queue, std::priority_queue가 있다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;std::stack&lt;/b&gt;&lt;/h3&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;std::stack은 std::deque을 기본 컨테이너로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 처리와 보관을 위해 LIFO(Last In First Out, 후입선출) 구조를 사용하고 한쪽 끝에서만 데이터의 삽입과 삭제가 이루어진다.&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;아래 코드에서 stack의 기본적인 함수들을 사용하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1673950977292&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;stack&amp;gt;
using namespace std;

int main(){
    stack&amp;lt;int&amp;gt; stack1;
    // deque에서의 push_back()함수를 사용하여 구현한다.
    stack1.push(1);
    stack1.push(2);
    stack1.push(3);

    cout &amp;lt;&amp;lt; &quot;stack1 size: &quot; &amp;lt;&amp;lt; stack1.size() &amp;lt;&amp;lt; &quot;\n&quot;; // 출력 stack1 size: 3

    // 출력: 3 2 1 (LIFO)
    while(!stack1.empty()){
        cout &amp;lt;&amp;lt; stack1.top() &amp;lt;&amp;lt; &quot;\t&quot;; // deque에서의 back() 함수를 사용한다.
        stack1.pop(); // deque에서의 pop_back() 함수를 사용한다.
    }

    cout &amp;lt;&amp;lt; &quot;\n&quot;;

    cout &amp;lt;&amp;lt; &quot;stack1 size: &quot; &amp;lt;&amp;lt; stack1.size() &amp;lt;&amp;lt; &quot;\n&quot;; // 출력 stack1 size: 0
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stack에서 vector가 아닌 deque을 사용하는 이유는 원소 저장 공간을 재할당할 때 vector는 전체 원소를 이동해야 하기 때문이다. 그렇기에 deque을 사용하는 것이 효율적인데, 경우에 따라 vector나 list를 사용할 때도 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 코드를 작성하면 vector나 list를 기본 컨테이너로 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1673951128424&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;stack&amp;lt;int, std::vector&amp;lt;int&amp;gt;&amp;gt; stk;
stack&amp;lt;int, std::list&amp;lt;int&amp;gt;&amp;gt; stk;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택의 모든 연산은 시간 복잡도가 O(1)이다. 스택에서 기본 컨테이너로 함수 호출을 전달하는 과정은 인라인(inline) 형식으로 호출될 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;std::queue&lt;/b&gt;&lt;/h3&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;stack은 LIFO 구조를 사용하지만 queue는 FIFO 구조를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;std::stack과 같은 이유로 std::deque을 기본 컨테이너로 사용하고, stack과 같은 방식으로 모든 함수는 시간 복잡도가 O(1)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 함수들은 다음과 같이 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1673951734189&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;
using namespace std;

int main(){
    queue&amp;lt;int&amp;gt; queue1;

    // deque의 push_back()을 사용한다.
    queue1.push(1);
    queue1.push(2);
    queue1.push(3);

    cout &amp;lt;&amp;lt; &quot;queue1 size: &quot; &amp;lt;&amp;lt; queue1.size() &amp;lt;&amp;lt; &quot;\n&quot;; // 출력: queue1 size: 3

    // 출력: 1 2 3 (FIFO)
    while (!queue1.empty()){
        cout &amp;lt;&amp;lt; queue1.front() &amp;lt;&amp;lt; &quot;\t&quot;;
        queue1.pop();
    }

    cout &amp;lt;&amp;lt; &quot;\nqueue1 size: &quot; &amp;lt;&amp;lt; queue1.size(); // 출력: queue1 size: 0
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;std::priority_queue&lt;/b&gt;&lt;/h3&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;priority queue는 heap 구조를 제공한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;heap은 컨테이너에서 가장 작거나 큰 원소에 빠르게 접근할 수 있는 자료구조로, 최소/최대 원소에 접근하는 동작은 O(1)의 시간복잡도를 갖고 원소 삽입은 O(logN) 시간복잡도로 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stack과 queue와 달리 priority_queue는 std::vector를 기본 컨테이너로 사용한다. (필요한 경우 변경 가능하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로는 비교자 std::less를 사용하여 최대 힙으로 생성되며, 이 또한 비교자를 이용하면 변경할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 원소를 삽입할 때마다 최대 또는 최소 원소가 최상위에 위치하도록 설정해야 하기 때문에 heapity 알고리즘을 구현해야 한다. (O(logn))&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 코드와 같이 간단하게 priority queue를 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1673953160884&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;
using namespace std;

int main(){
    priority_queue&amp;lt;int&amp;gt; priorityQueue1;

    priorityQueue1.push(1);
    priorityQueue1.push(2);
    priorityQueue1.push(3);
    priorityQueue1.push(5);
    priorityQueue1.push(7);
    priorityQueue1.push(2);
    priorityQueue1.push(20);
    priorityQueue1.push(1);

    cout &amp;lt;&amp;lt; &quot;priorityQueue1 size: &quot; &amp;lt;&amp;lt; priorityQueue1.size() &amp;lt;&amp;lt; &quot;\n&quot;; // 출력: priorityQueue1 size: 3

    // 출력: 20      7       5       3       2       2       1       1
    while (!priorityQueue1.empty()){
        cout &amp;lt;&amp;lt; priorityQueue1.top() &amp;lt;&amp;lt; &quot;\t&quot;;
        priorityQueue1.pop();
    }

    cout &amp;lt;&amp;lt; &quot;\npriorityQueue1 size: &quot; &amp;lt;&amp;lt; priorityQueue1.size(); // 출력: priorityQueue1 size: 0


    priority_queue&amp;lt;int, vector&amp;lt;int&amp;gt;, greater&amp;lt;int&amp;gt;&amp;gt; priorityQueue2;

    priorityQueue2.push(1);
    priorityQueue2.push(2);
    priorityQueue2.push(3);
    priorityQueue2.push(5);
    priorityQueue2.push(7);
    priorityQueue2.push(2);
    priorityQueue2.push(20);
    priorityQueue2.push(1);

    cout &amp;lt;&amp;lt; &quot;priorityQueue1 size: &quot; &amp;lt;&amp;lt; priorityQueue2.size() &amp;lt;&amp;lt; &quot;\n&quot;; // 출력: priorityQueue2 size: 3

    // 출력: 1       1       2       2       3       5       7       20
    while (!priorityQueue2.empty()){
        cout &amp;lt;&amp;lt; priorityQueue2.top() &amp;lt;&amp;lt; &quot;\t&quot;;
        priorityQueue2.pop();
    }

    cout &amp;lt;&amp;lt; &quot;\npriorityQueue2 size: &quot; &amp;lt;&amp;lt; priorityQueue2.size(); // 출력: priorityQueue2 size: 0

}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경우에 따라 다른 컨테이너를 사용해야 할 텐데, 어떤 경우에 어떤 컨테이너가 맞는지 알기 위해 작은 프로토 타입을 만들고 성능을 측정하는 과정도 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://quick-bench.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://quick-bench.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1673953264196&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Quick C++ Benchmarks&quot; data-og-description=&quot;Quickly benchmark C++ runtimes&quot; data-og-host=&quot;quick-bench.com&quot; data-og-source-url=&quot;https://quick-bench.com/&quot; data-og-url=&quot;https://quick-bench.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBoQ4H/hyRkrxaIZh/3b3kmVjvLSsBsG259L6jGk/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/3RaQ0/hyRkotFEoE/f9aafGcsUbnOaCSA4U7ncK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://quick-bench.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://quick-bench.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBoQ4H/hyRkrxaIZh/3b3kmVjvLSsBsG259L6jGk/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/3RaQ0/hyRkotFEoE/f9aafGcsUbnOaCSA4U7ncK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Quick C++ Benchmarks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Quickly benchmark C++ runtimes&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;quick-bench.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;벤치마킹을 쉽게 수행할 수 있는 벤치마킹 프로그램의 도움을 받아 결과를 비교해볼 수 있다.&lt;/p&gt;</description>
      <category>알고리즘/알고리즘 공부</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/58</guid>
      <comments>https://haram17-devlog.tistory.com/58#entry58comment</comments>
      <pubDate>Tue, 17 Jan 2023 20:01:50 +0900</pubDate>
    </item>
    <item>
      <title>[1. 리스트, 스택, 큐] C++ std::deque</title>
      <link>https://haram17-devlog.tistory.com/57</link>
      <description>&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;std::deque&lt;/b&gt;&lt;/h3&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;벡터는 가변 길이 배열이고, push_front() 또는 pop_front() 같은 함수는 비용이 많이 든다. (다 하나씩 밀어줘야 함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;std::deque를 통해 이런 단점을 극복할 수 있다. (double-ended queue)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;덱(deque)의 구조&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;- push_front(), pop_front(), push_back(), pop_back() 동작이 O(1) 시간 복잡도로 동작해야 한다.&lt;br /&gt;- 모든 원소에 대해 임의 접근 동작이 O(1) 시간 복잡도로 동작해야 한다.&lt;br /&gt;- 덱 중간에서 원소 삽입 또는 삭제는 O(n) 시간 복잡도로 동작해야 하며, 실제로는 최대 n/2 단계로 동작한다. (n: 덱의 크기)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 덱은 자료구조가 벡터와 비슷하지만 앞쪽과 뒤쪽으로 보두 확장할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 원소 삽입 시 해당 위치에서 가장 가까운 끝 쪽으로 나머지 원소를 이동하기에 n/2 단계의 시간 복잡도를 갖는다.&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;- 벡터와 리스트에서 제공되는 함수를 조합한 것 이상의 기능을 제공한다. (capacity() 함수는 지원되지 않는다.)&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;div&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;deque&amp;gt;
using namespace std;
int main(){
    deque&amp;lt;int&amp;gt; deq = {1, 2, 3, 4, 5};
    deq.push_front(0); // {0, 1, 2, 3, 4, 5}
    deq.push_back(6); // {0, 1, 2, 3, 4, 5, 6}

    deq.insert(deq.begin() + 2, 10); // {0, 1, 10, 2, 3, 4, 5, 6}

    deq.pop_back(); // {0, 1, 10, 2, 3, 4, 5}
    deq.pop_front(); // {1, 10, 2, 3, 4, 5}

    deq.erase(deq.begin() + 1); // {1, 2, 3, 4, 5}

    deq.erase(deq.begin() + 3, deq.end()); // {1, 2, 3}

    for(auto i : deq)
        cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot; &quot;;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;덱은 데이터 맨 뒤와 맨 앞에서도 매우 빠르게 원소의 삽입과 삭제가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 데이터 중간에서의 삽입 또는 삭제에 대한 시간복잡도는 벡터와 같지만, 실제로는 벡터보다 약간 더 빠르다.&lt;/p&gt;</description>
      <category>알고리즘/알고리즘 공부</category>
      <author>꿀꺽람</author>
      <guid isPermaLink="true">https://haram17-devlog.tistory.com/57</guid>
      <comments>https://haram17-devlog.tistory.com/57#entry57comment</comments>
      <pubDate>Sun, 15 Jan 2023 23:21:08 +0900</pubDate>
    </item>
  </channel>
</rss>