{"componentChunkName":"component---src-templates-blog-post-js","path":"/Problem-Solving/2020-05-05-백준-가운데를-말해요/","result":{"data":{"site":{"siteMetadata":{"title":"Hun's Footsteps 🥷","author":"전여훈","siteUrl":"https://jeonyeohun.netlify.app","comment":{"disqusShortName":"","utterances":"jeonyeohun/jeonyeohun.github.io"},"sponsor":{"buyMeACoffeeId":"jeonyeohun"}}},"markdownRemark":{"id":"a01667d4-53d3-54fc-96d1-692a22a3808c","excerpt":"https://www.acmicpc.net/problem/1655 문제 문제\n수빈이는 동생에게 “가운데를 말해요” 게임을 가르쳐주고 있다. 수빈이가 정수를 하나씩 외칠때마다 동생은 지금까지 수빈이가 말한 수 중에서 중간값을 말해야 한다. 만약, 그동안 수빈이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 말해야 한다. 예를 들어 수빈이가 동생에게 1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2,…","html":"<p><a href=\"https://www.acmicpc.net/problem/1655\">https://www.acmicpc.net/problem/1655</a></p>\n<h2 id=\"문제\" style=\"position:relative;\"><a href=\"#%EB%AC%B8%EC%A0%9C\" aria-label=\"문제 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>문제</h2>\n<p><strong>문제</strong><br>\n수빈이는 동생에게 “가운데를 말해요” 게임을 가르쳐주고 있다. 수빈이가 정수를 하나씩 외칠때마다 동생은 지금까지 수빈이가 말한 수 중에서 중간값을 말해야 한다. 만약, 그동안 수빈이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 말해야 한다.</p>\n<p>예를 들어 수빈이가 동생에게 1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2, 5를 차례대로 말해야 한다. 수빈이가 외치는 수가 주어졌을 때, 동생이 말해야 하는 수를 구하는 프로그램을 작성하시오.</p>\n<p><strong>입력</strong><br>\n첫째 줄에는 수빈이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -10,000보다 크거나 같고, 10,000보다 작거나 같다.</p>\n<p><strong>출력</strong><br>\n한 줄에 하나씩 N줄에 걸쳐 수빈이의 동생이 말해야하는 수를 순서대로 출력한다.</p>\n<h2 id=\"풀이\" style=\"position:relative;\"><a href=\"#%ED%92%80%EC%9D%B4\" aria-label=\"풀이 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>풀이</h2>\n<p>힙소트를 계속 해주면서 중간 인덱스를 참조하는 문제인 줄 알았는데 완전히 낭패였다. 시간초과가 계속 나서 어떻게 해결해야할지 고민하다 답이 안나오는 것 같아 구글링으로 도움을 받았다. 이 문제는 우선순위 큐 두개를 사용해서 push 와 pop만을 사용해서 해결해야 했다. Heapsort는 Օ(nlogn) 으로 절대로 느리지는 않지만, 이 문제에는 적합하지 않다. push 와 pop 은 Օ(lg n)의 시간복잡도를 가지는데, 트리의 높이만큼 부모노드와 자식노드의 비교 및 교환을 수행하기 때문이다.</p>\n<p>두 개의 우선순위 큐를 사용해서 문제를 해결하는 방법은 다음과 같다.</p>\n<ol>\n<li>최대 우선순위 큐, 최소 우선순위 큐 두 개를 준비한다.</li>\n<li>최소 우선순위 큐는 항상 최대 우선순위 큐 보다 큰 값을 가진다.</li>\n<li>최대 우선순위 큐는 항상 최소 우선순위 큐 보다 같거나 많은 노드를 가진다.</li>\n</ol>\n<p>이 구조를 유지하게되면, 어떤 값이 들어왔을 때, 총 노드의 개수가 짝수일 때는 자연스럽게 최대 우선순위 큐에 값을 넣게 된다. 이 때 최댓값이 큐의 top의 위치하게 되기 때문에, 최소 우선순위 큐의 top에 있는 노드의 값과 비교해주어야할 필요가 생긴다. 왜냐하면 최대 우선순위 큐가 최소 우선순위 큐보다 하나 더 많은 노드를 갖게하는 것이 중간 값을 최대 큐에 저장하기 위해서인데, 만약 새로 들어온 값이 최소 큐의 top보다 크다면, 현재 최소 큐의 top에 있는 값이 중간값이 되기 때문이다. 이 구조를 유지하기 위해서 양쪽 노드를 조건에 따라 swap 하면서 최대 큐의 top을 계속 출력해주면 중간값을 지속적으로 얻을 수 있다.</p>\n<h2 id=\"코드\" style=\"position:relative;\"><a href=\"#%EC%BD%94%EB%93%9C\" aria-label=\"코드 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>코드</h2>\n<div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;cstdio></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;vector></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;queue></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;functional></span></span>\n\n<span class=\"token keyword\">using</span> <span class=\"token keyword\">namespace</span> std<span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">int</span> N<span class=\"token punctuation\">;</span>\n    <span class=\"token function\">scanf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>N<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    priority_queue<span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">,</span> vector<span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token operator\">></span><span class=\"token punctuation\">,</span> less<span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token operator\">>></span> pqMax<span class=\"token punctuation\">;</span>\n    priority_queue<span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">,</span> vector<span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token operator\">></span><span class=\"token punctuation\">,</span> greater<span class=\"token operator\">&lt;</span><span class=\"token keyword\">int</span><span class=\"token operator\">>></span> pqMin<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">while</span><span class=\"token punctuation\">(</span>N<span class=\"token operator\">--</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">int</span> n<span class=\"token punctuation\">;</span>\n        <span class=\"token function\">scanf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">empty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">||</span> pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> pqMin<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span> <span class=\"token comment\">// 무조건 최대 큐에 들어가야하는 경우</span>\n            pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">push</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n            pqMin<span class=\"token punctuation\">.</span><span class=\"token function\">push</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">empty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">!</span>pqMin<span class=\"token punctuation\">.</span><span class=\"token function\">empty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>pqMin<span class=\"token punctuation\">.</span><span class=\"token function\">top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span> <span class=\"token comment\">// 최대 큐는 항상 최소 작거나 같은 값을 가져야 한다.</span>\n                <span class=\"token keyword\">int</span> tempMax <span class=\"token operator\">=</span> pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">int</span> tempMin <span class=\"token operator\">=</span> pqMin<span class=\"token punctuation\">.</span><span class=\"token function\">top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">pop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                pqMin<span class=\"token punctuation\">.</span><span class=\"token function\">pop</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n                pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">push</span><span class=\"token punctuation\">(</span>tempMin<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                pqMin<span class=\"token punctuation\">.</span><span class=\"token function\">push</span><span class=\"token punctuation\">(</span>tempMax<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> pqMax<span class=\"token punctuation\">.</span><span class=\"token function\">top</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>","frontmatter":{"title":"[백준 알고리즘] 1655번: 가운데를 말해요","date":"May 05, 2020"}}},"pageContext":{"slug":"/Problem-Solving/2020-05-05-백준-가운데를-말해요/","previous":{"fields":{"slug":"/Algorithm-Analysis/2020-04-25-알고리즘-BFS/"},"frontmatter":{"title":"[알고리즘 정리] 너비 우선 탐색(BFS)","category":"Algorithm-Analysis","draft":false}},"next":{"fields":{"slug":"/Problem-Solving/2020-05-04-백준-미로탐색/"},"frontmatter":{"title":"[백준 알고리즘] 2178번: 미로탐색","category":"Problem-Solving","draft":false}}}},"staticQueryHashes":["2486386679","3128451518"]}