<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>shinhn_peanut.log</title>
        <link>https://velog.io/</link>
        <description>땅콩의 모험 (server)</description>
        <lastBuildDate>Tue, 14 Jan 2025 13:25:58 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>shinhn_peanut.log</title>
            <url>https://images.velog.io/images/peanut_/profile/96170e79-a1a7-4f5e-ac80-9eee6a84bdec/62635727.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. shinhn_peanut.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/peanut_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[React] GitHub Pages 로 무료 호스팅하는 법]]></title>
            <link>https://velog.io/@peanut_/React-Git-pages-%EB%B0%B0%ED%8F%AC</link>
            <guid>https://velog.io/@peanut_/React-Git-pages-%EB%B0%B0%ED%8F%AC</guid>
            <pubDate>Tue, 14 Jan 2025 13:25:58 GMT</pubDate>
            <description><![CDATA[<h1 id="1-github-pages">1. GitHub Pages</h1>
<blockquote>
<p>GitHub Pages는 GitHub의 Repository의 올린 코드에 따라 웹 페이지를 간단하게 호스팅할 수 있는 깃허브의 기능</p>
</blockquote>
<ul>
<li>일반적으로 웹에 호스팅을 하려면 돈을 내고 또는 무료로 저성능의 서버를 얻고 호스팅을 하는데, 금전적인 문제가 생기거나, 무료로 하려면 세팅이 번거로움</li>
<li>GitHub Pages을 쓰는게 매우 간편</li>
<li>기본적으로 pages는 최상위 폴더(root)의 index.html을 가리키며, 해당 파일이 존재하지 않으면 README.md를 띄워준다고 함</li>
</ul>
<h1 id="2-settings">2. Settings</h1>
<h2 id="2-1-gh-pages-패키지-설치">2-1. gh-pages 패키지 설치</h2>
<pre><code>npm install gh-pages</code></pre><h2 id="2-2-repository">2-2. Repository</h2>
<p><img src="https://velog.velcdn.com/images/peanut_/post/4e7c8c67-3e39-4d63-a906-ffe645195a52/image.png" alt=""></p>
<ul>
<li>소스가 올라가 있는 레포 설정에서 브랜치를 gh-pages로 바꿔주고
좀 기다리면 위에 호스팅 url이 생김 (<a href="https://shinhn.github.io/React/">https://shinhn.github.io/React/</a>)</li>
</ul>
<h2 id="2-3-packagejson-수정">2-3. package.json 수정</h2>
<p><img src="https://velog.velcdn.com/images/peanut_/post/00cb0c57-e03f-4eba-8b9a-17ba22c3697f/image.png" alt=""></p>
<ol>
<li>package.json 에 필요한 옵션 추가
(참고) 배포할 때 에러 나서 deploy 명령어를 빌드 할 때 생기는 문서 이름인 dist로 바꿔주니 잘 되더라</li>
</ol>
<pre><code>    &quot;predeploy&quot;: &quot;npm run build&quot;
    &quot;deploy&quot;: &quot;gh-pages -d dist&quot; 
    &quot;homepage&quot;: &quot;https://shinhn.github.io/React/&quot;</code></pre><ol start="2">
<li>소스 한번 더 git에 올려주고</li>
</ol>
<h2 id="2-4-빌드-및-배포">2-4. 빌드 및 배포</h2>
<ol>
<li>JSX 파일을 브라우저에 띄우기 위해서 브라우저가 이해할 수 있는 언어인 SS, JS, HTML 문법으로 바꿔주는 작업이 필요한데, 이걸 컴파일 또는 build라고 함</li>
<li>터미널에서 빌드하면 dist에 필요한 문서가 생기는 걸 볼 수 있음<pre><code>npm run build</code></pre></li>
<li>터미널에서 deploy 해줬을 때 아래처럼 되면 잘 된 거<pre><code>npm run deploy</code></pre><img src="https://velog.velcdn.com/images/peanut_/post/432b0a93-5c9e-47e5-911d-8e55c410c47f/image.png" alt=""></li>
</ol>
<h1 id="3-result">3. Result</h1>
<p>이제 <a href="https://shinhn.github.io/React/">https://shinhn.github.io/React/</a> 들어가보면 호스팅 되어 있는 걸 알 수 있음</p>
<p>강의 들으면서 이것저것 갖다 붙인 거라 결과물이 너무 조잡한 관계로 결과는 스킵.. 암튼 잘 호스팅 되더라~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 체육복]]></title>
            <link>https://velog.io/@peanut_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B2%B4%EC%9C%A1%EB%B3%B5</link>
            <guid>https://velog.io/@peanut_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B2%B4%EC%9C%A1%EB%B3%B5</guid>
            <pubDate>Wed, 05 Apr 2023 07:24:04 GMT</pubDate>
            <description><![CDATA[<p>✅ vector.erase()</p>
<h1 id="문제">문제</h1>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42862#">https://school.programmers.co.kr/learn/courses/30/lessons/42862#</a></p>
<h1 id="풀이">풀이</h1>
<h2 id="--vectorerase">- vector.erase()</h2>
<blockquote>
<ol>
<li>특정 인덱스 삭제
v.erase(v.begin() + idx);</li>
<li>특정 범위 모든 값 삭제
v.erase(v.begin(), v.end());</li>
</ol>
</blockquote>
<h2 id="--참고-remove">- (참고) remove()</h2>
<blockquote>
<p>특정 값 삭제
remove(v.begin(), v.end(), num);</p>
</blockquote>
<hr>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(int n, vector&lt;int&gt; lost, vector&lt;int&gt; reserve) {
    int answer = 0;

    for(int i=0;i&lt;lost.size();i++){
        for(int j=0;j&lt;reserve.size();j++){
            if(lost[i] == reserve[j]){ // 여벌 체육복을 가져온 학생이 체육복을 도난당한 경우 -&gt; 남은 체육복이 하나이기에 두 벡터에서 모두 제거
                lost.erase(lost.begin()+i);
                reserve.erase(reserve.begin()+j);

                i--; // lost 벡터에서 원소 하나를 지웠으므로 반복문 인덱스도 한칸 줄임
            }
        }
    }

    // 맨 앞부터 체육복을 빌려주기(greedy) 위한 정렬
    sort(lost.begin(), lost.end());
    sort(reserve.begin(), reserve.end());

    answer = n - lost.size();

    for(int i=0;i&lt;lost.size();i++){
        for(int j=0;j&lt;reserve.size();j++){
            if(lost[i]-1 == reserve[j] || lost[i]+1 == reserve[j]){ // 바로 앞이나 뒤에 빌려줄 사람이 있는 경우
                answer++;
                reserve.erase(reserve.begin()+j);
                break;
            }
        }
    }

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[MYSQL 코딩테스트 문법정리]]></title>
            <link>https://velog.io/@peanut_/MYSQL-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%AC%B8%EB%B2%95%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@peanut_/MYSQL-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%AC%B8%EB%B2%95%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 04 Apr 2023 01:08:48 GMT</pubDate>
            <description><![CDATA[<h1 id="select-from">SELECT, FROM</h1>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME FROM ANIMAL_INS;
SELECT ANIMAL_ID, NAME AS &#39;이름&#39; FROM ANIMAL_INS;</code></pre>
<hr>
<h1 id="where">WHERE</h1>
<h2 id="--and-or">- AND, OR</h2>
<pre><code class="language-sql">SELECT userID, Name FROM usertbl WHERE birthYear &gt;= 1970 AND height &gt;= 182;
SELECT userID, Name FROM usertbl WHERE birthYear &gt;= 1970 OR height &gt;= 182;</code></pre>
<h2 id="--between-a-and-b">- BETWEEN A AND B</h2>
<pre><code class="language-sql">SELECT name, height FROM usertbl WHERE height BETWEEN 180 AND 183;</code></pre>
<h2 id="--in-ab--c">- IN (&#39;A&#39;,&#39;B&#39; ... &#39;C&#39;)</h2>
<pre><code class="language-sql">SELECT name, addr FROM usertbl WHERE addr IN (&#39;경남&#39;,&#39;전남&#39;,&#39;경북&#39;);</code></pre>
<h2 id="--like-">- LIKE &#39;%~%&#39;</h2>
<pre><code class="language-sql">SELECT name, height FROM usertbl WHERE name LIKE &#39;김%&#39;;</code></pre>
<hr>
<h1 id="order-by">ORDER BY</h1>
<ul>
<li>동물 보호소에 들어온 모든 동물의 아이디와 이름, 보호 시작일을 이름 순으로 조회</li>
<li>단, 이름이 같은 동물 중에서는 보호를 나중에 시작한 동물을 먼저 조회</li>
</ul>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME, DATETIME FROM ANIMAL_INS ORDER BY NAME, DATETIME DESC;</code></pre>
<hr>
<h1 id="limit">LIMIT</h1>
<ul>
<li>동물 보호소에 가장 먼저 들어온 동물의 이름을 조회<pre><code class="language-sql">SELECT NAME FROM ANIMAL_INS ORDER BY DATETIME LIMIT 1;</code></pre>
</li>
</ul>
<hr>
<h1 id="sum-max-min">SUM, MAX, MIN</h1>
<ul>
<li><p>가장 최근에 들어온 동물은 언제 들어왔는지 조회</p>
<pre><code class="language-sql">SELECT MAX(DATETIME) AS &#39;시간&#39; FROM ANIMAL_INS;</code></pre>
</li>
<li><p>가장 먼저 들어온 동물은 언제 들어왔는지 조회</p>
</li>
</ul>
<pre><code class="language-sql">SELECT MIN(DATETIME) AS &#39;시간&#39; FROM ANIMAL_INS;</code></pre>
<hr>
<h1 id="group-by">GROUP BY</h1>
<ul>
<li>고양이와 개가 각각 몇 마리인지 조회</li>
<li>이때 고양이를 개보다 먼저 조회</li>
</ul>
<pre><code class="language-sql">SELECT ANIMAL_TYPE, COUNT(ANIMAL_TYPE) AS &#39;count&#39; FROM ANIMAL_INS GROUP BY ANIMAL_TYPE ORDER BY ANIMAL_TYPE;</code></pre>
<h2 id="--having">- HAVING</h2>
<ul>
<li>동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회</li>
<li>이름이 없는 동물은 집계에서 제외하며, 결과는 이름 순으로 조회</li>
</ul>
<pre><code class="language-sql">SELECT NAME, COUNT(NAME) AS &#39;COUNT&#39; FROM ANIMAL_INS GROUP BY NAME HAVING COUNT &gt;= 2 ORDER BY NAME;</code></pre>
<hr>
<h1 id="case-when">CASE WHEN</h1>
<p><img src="https://velog.velcdn.com/images/peanut_/post/905fa819-b79a-42de-ab0a-59fcff68fd85/image.png" alt=""></p>
<hr>
<h1 id="truncate숫자버릴-자릿수">TRUNCATE(숫자,버릴 자릿수)</h1>
<p><img src="https://velog.velcdn.com/images/peanut_/post/2f1720a9-0814-437a-97c7-584772af1382/image.png" alt=""></p>
<ul>
<li>만원 단위의 가격대 별로 상품 개수를 출력</li>
<li>이때 컬럼명은 각각 컬럼명은 PRICE_GROUP, PRODUCTS로 지정</li>
<li>가격대 정보는 각 구간의 최소금액(10,000원 이상 ~ 20,000 미만인 구간인 경우 10,000)으로 표시</li>
<li>가격대를 기준으로 오름차순 정렬</li>
</ul>
<pre><code class="language-sql">SELECT TRUNCATE(PRICE, -4) AS PRICE_GROUP, COUNT(*) AS PRODUCTS
FROM PRODUCT GROUP BY PRICE_GROUP ORDER BY PRICE_GROUP;</code></pre>
<hr>
<h1 id="left-join">LEFT JOIN</h1>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/133026">https://school.programmers.co.kr/learn/courses/30/lessons/133026</a></p>
<pre><code class="language-sql">SELECT INGREDIENT_TYPE, SUM(TOTAL_ORDER) AS TOTAL_ORDER
FROM FIRST_HALF LEFT JOIN ICECREAM_INFO ON FIRST_HALF.FLAVOR = ICECREAM_INFO.FLAVOR
GROUP BY INGREDIENT_TYPE;</code></pre>
<hr>
<h1 id="is-null">IS NULL</h1>
<ul>
<li>이름이 없는 동물의 ID를 조회</li>
</ul>
<pre><code class="language-sql">SELECT ANIMAL_ID FROM ANIMAL_INS WHERE NAME IS NULL;</code></pre>
<ul>
<li>이름이 있는 동물의 ID를 조회</li>
</ul>
<pre><code class="language-sql">SELECT ANIMAL_ID FROM ANIMAL_INS WHERE NAME IS NOT NULL;</code></pre>
<hr>
<h1 id="date_format">DATE_FORMAT</h1>
<h2 id="--yyyymmdd-포맷">- YYYY/mm/dd 포맷</h2>
<pre><code class="language-sql">SELECT DATE_FORMAT(&#39;20200405&#39;,&#39;%Y/%m/%d&#39;)</code></pre>
<pre><code>-&gt; 2020/04/05</code></pre><h2 id="--yyyy-mm-dd-포맷">- YYYY-mm-dd 포맷</h2>
<pre><code class="language-sql">SELECT DATE_FORMAT(&#39;20200405&#39;,&#39;%Y-%m-%d&#39;)</code></pre>
<pre><code>-&gt; 2020-04-05</code></pre><h2 id="--영어-표기로-변환">- 영어 표기로 변환</h2>
<pre><code class="language-sql">SELECT DATE_FORMAT(&#39;2020-04-05&#39;, &#39;%W %M %Y&#39;);</code></pre>
<pre><code>-&gt; Sunday April 2020</code></pre><h2 id="--여러-지정값">- 여러 지정값</h2>
<p><a href="https://ponyozzang.tistory.com/656">DATE_FORMAT 지정값</a></p>
<hr>
<h1 id="datediff">DATEDIFF</h1>
<ul>
<li>대여 시작일이 2022년 9월에 속하는 대여 기록에 대해서</li>
<li>대여 기간이 30일 이상이면 &#39;장기 대여&#39; 그렇지 않으면 &#39;단기 대여&#39; 로 표시하는 컬럼(컬럼명: RENT_TYPE)을 추가하여 대여기록을 출력</li>
<li>결과는 대여 기록 ID를 기준으로 내림차순 정렬</li>
</ul>
<pre><code class="language-sql">SELECT
    HISTORY_ID,
    CAR_ID,
    DATE_FORMAT(START_DATE, &#39;%Y-%m-%d&#39;) AS START_DATE,
    DATE_FORMAT(END_DATE, &#39;%Y-%m-%d&#39;) AS END_DATE,
    CASE
        WHEN DATEDIFF(END_DATE, START_DATE) + 1 &gt;= 30 THEN &quot;장기 대여&quot;
        ELSE &quot;단기 대여&quot;
    END AS RENT_TYPE
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE START_DATE BETWEEN &#39;2022-09-01&#39; AND &#39;2022-09-30&#39;
ORDER BY HISTORY_ID DESC;</code></pre>
<ul>
<li>유의할 점은 오늘 대여하고 오늘 반납해도 대여 기간은 하루이기 때문에
(END_DATE - START_DATE ) + 1 &gt;= 30으로 계산해야 함</li>
</ul>
<hr>
<h1 id="reference">Reference</h1>
<p><a href="https://school.programmers.co.kr/learn/challenges?tab=sql_practice_kit">https://school.programmers.co.kr/learn/challenges?tab=sql_practice_kit</a>
<a href="https://paris-in-the-rain.tistory.com/100">https://paris-in-the-rain.tistory.com/100</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 전력망을 둘로 나누기]]></title>
            <link>https://velog.io/@peanut_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%84%EB%A0%A5%EB%A7%9D%EC%9D%84-%EB%91%98%EB%A1%9C-%EB%82%98%EB%88%84%EA%B8%B0</link>
            <guid>https://velog.io/@peanut_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%84%EB%A0%A5%EB%A7%9D%EC%9D%84-%EB%91%98%EB%A1%9C-%EB%82%98%EB%88%84%EA%B8%B0</guid>
            <pubDate>Fri, 31 Mar 2023 09:37:35 GMT</pubDate>
            <description><![CDATA[<p>✅ 완전탐색 ✅ dfs ✅ 연결요소 크기</p>
<h1 id="문제">문제</h1>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/86971">https://school.programmers.co.kr/learn/courses/30/lessons/86971</a></p>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>전선이 하나 끊어진 모든 경우에 따라
dfs로 두개의 네트워크의 크기를 구하는 문제</p>
</blockquote>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;iostream&gt;

using namespace std;

int graph[101][101];
bool visited[101];

int dfs(int node, int n){
    if(visited[node]) return 0;
    visited[node] = true;

    int network_size = 1;

    for(int i=1;i&lt;=n;i++){
        if(graph[node][i] == 1){
            network_size += dfs(i, n);
        }
    }

    return network_size;
}

int solution(int n, vector&lt;vector&lt;int&gt;&gt; wires) {
    int answer = 100;

    for(int i=0;i&lt;wires.size();i++){
        int n1 = wires[i][0];
        int n2 = wires[i][1];
        graph[n1][n2] = 1;
        graph[n2][n1] = 1;
    }

    for(int i=0;i&lt;wires.size();i++){
        // 전선 하나 끊음
        int n1 = wires[i][0];
        int n2 = wires[i][1];
        graph[n1][n2] = 0;
        graph[n2][n1] = 0;

        // 초기화
        fill(visited, visited + 101, false);

        // 각 네트워크 사이즈 측정
        vector&lt;int&gt; net_sizes;
        for(int j=1;j&lt;=n;j++){
            int net_size = dfs(j, n);
            if(net_size != 0) net_sizes.push_back(net_size);
        }

        if(abs(net_sizes[0] - net_sizes[1]) &lt; answer){
            answer = abs(net_sizes[0] - net_sizes[1]);
        }

        // 다시 전선 연결
        graph[n1][n2] = 1;
        graph[n2][n1] = 1;
    }

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s3) 10974 모든 순열]]></title>
            <link>https://velog.io/@peanut_/boj-s3-10974-%EB%AA%A8%EB%93%A0-%EC%88%9C%EC%97%B4</link>
            <guid>https://velog.io/@peanut_/boj-s3-10974-%EB%AA%A8%EB%93%A0-%EC%88%9C%EC%97%B4</guid>
            <pubDate>Fri, 03 Feb 2023 11:05:50 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/10974">https://www.acmicpc.net/problem/10974</a></p>
<h1 id="풀이">풀이</h1>
<h2 id="1-stl-사용">1. STL 사용</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int N;
vector&lt;int&gt; arr;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N;

    for(int i=1;i&lt;=N;i++){
        arr.push_back(i);
    }

    do{
        for(int i=0;i&lt;N;i++){
            cout &lt;&lt; arr[i] &lt;&lt; &quot; &quot;;
        }
        cout &lt;&lt; &quot;\n&quot;;
    }while(next_permutation(arr.begin(), arr.end()));

    return 0;
}</code></pre>
<h2 id="2-직접-구현-브루트포스-dfs">2. 직접 구현 (브루트포스, dfs)</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int N;
int arr[9];
bool used[9];

void func(int idx){
    if(idx == N){
        for(int i=0;i&lt;N;i++){
            cout &lt;&lt; arr[i] &lt;&lt; &quot; &quot;;
        }
        cout &lt;&lt; &quot;\n&quot;;
    }

    for(int i=1;i&lt;=N;i++){
        if(used[i] == true) continue;

        used[i] = true;
        arr[idx] = i;
        func(idx+1);
        used[i] = false;
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N;

    func(0);

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Union Find (예제 : boj 1717 집합의 표현)]]></title>
            <link>https://velog.io/@peanut_/Union-Find-%EC%98%88%EC%A0%9C-boj-1717-%EC%A7%91%ED%95%A9%EC%9D%98-%ED%91%9C%ED%98%84</link>
            <guid>https://velog.io/@peanut_/Union-Find-%EC%98%88%EC%A0%9C-boj-1717-%EC%A7%91%ED%95%A9%EC%9D%98-%ED%91%9C%ED%98%84</guid>
            <pubDate>Wed, 25 Jan 2023 01:33:38 GMT</pubDate>
            <description><![CDATA[<h1 id="union-find">Union Find</h1>
<blockquote>
<p>상호 배타적 집합(disjoint set)을 표현하는데에 쓰는 자료구조이다.
상호 배타적 집합은, 서로 공통원소가 없는 집합을 의미한다.</p>
</blockquote>
<h1 id="필요한-이유">필요한 이유</h1>
<p>어떤 파티에 n명의 사람이 왔다고 하자. 레크레이션 강사가 생일이 같은 사람들끼리 뭉치라고 했을 때, 처음에는 모두 혼자 돌아다니다, 생일이 같은 사람을 찾게 되면 그 사람들 끼리는 팀을 이루어 함께 움직이게 된다. 다른 팀을 만났을 때, 생일이 같다는것을 알게 되면 두 팀은 뭉쳐서 한 팀을 구성하는 식으로 움직인다.</p>
<p>파티에 온 사람들의 전체 집합으로 놓고 보면, 팀은 이 집합을 여러개의 부분집합으로 쪼갠것 이다. 각 팀은 생일이 같은 사람들로 구성되었기 때문에, 두 개 이상의 팀에 속한 사람은 없다는 점에 유의하자. 이렇게 공통 원소가 없는, 다시말해 상호 배타적인 부분 집합들로 나눠진 원소들에 대한 정보를 저장하고 조작하는 자료 구조가 바로 유니온-파인드 구조이다.</p>
<p>이러한 것들을 컴퓨터 언어에서 다룰 수 있게 해주는 유니온-파인드 구조가 할 수 있어야 하는 연산은 다음과 같다.</p>
<blockquote>
<ol>
<li>초기화 : n개의 원소가 각각의 집합에 포함되어 있도록 초기화</li>
<li>합치기(union) 연산 : 두 원소 a,b가 주어질 때, 이들이 속한 두 집합을 하나로 합침</li>
<li>찾기(find) 연산 : 어떤 원소 a가 주어질 때 이 원소가 속한 집합을 반환</li>
</ol>
</blockquote>
<p>초기화 연산은 처음 구조를 만들때 외에는 그렇게 자주 쓰지 않으니, 상대적으로 자주 쓰는 두 연산의 이름을 따서 union-find 자료구조라고 한다.</p>
<hr>
<h1 id="구현1-배열">구현1 (배열)</h1>
<p>union-find 자료구조를 구현하는 가장 간단한 방법은 1차원 배열 하나를 이용해서 아래와 같이 만드는 것이다.</p>
<pre><code>belongsTo[i] = i번 원소가 속하는 집합의 번호</code></pre><p>처음에는 belongsTo[i] = i로 두면, 찾기 연산을 상수 시간안에 할 수 있다.</p>
<p>하지만 이 방법의 문제는 합치기 연산이다. 합치기 연산을 위해서는 belongsTo[]의 모든 원소를 순회하면서 한쪽 집합에 속한 원소들을 다른쪽 원소의 집합으로 옮겨야 하는데, 모든 원소를 순회하는데에는 O(N)의 시간이 걸린다.</p>
<p><strong>찾기 연산이 O(1)이라는 사실은 매우 좋으나, 합치기 연산의 비용이 크기 때문에 다른 방법을 고안해볼 필요가 있다.</strong></p>
<h1 id="구현2-트리">구현2 (트리)</h1>
<p>배열표현의 &quot;합치기 연산이 느리다&quot;라는 단점을 극복하는 좋은 방법 중 하나는, 트리를 이용해서 이를 구현하는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/peanut_/post/8ba07edf-fed0-4b08-9e95-cfa74a864757/image.png" alt=""></p>
<blockquote>
<p>두 원소가 같은 트리에 속해있는지 확인하는 방법인 <strong>찾기(find) 연산</strong>
👉 <strong>원소가 속해있는 트리의 루트가 같은지를 비교</strong>하는 것</p>
</blockquote>
<pre><code class="language-cpp">int parent[1000001];

int find(int node){ // 같은 집합인지 확인 (같은 뿌리인지 확인)
    if(parent[node] == node) return node; // 뿌리 노드일 경우 본인 리턴
    else return parent[node] = find(parent[node]); // 경로 압축 최적화
}

void uni(int a, int b){ // 합집합 (a 집합을 b 집합의 자식노드로 합침)
    int rootA = find(a);
    int rootB = find(b);

    parent[rootA] = rootB;
}

void init(){ // 부모 배열 초기화
    for(int i=0;i&lt;=n;i++){
        parent[i] = i;
    }
}</code></pre>
<ul>
<li><p>트리와 루트는 항상 1:1 대응되므로(루트가 2개 이상 있는 트리는 존재하지 않으니까) 루트가 같다면 두 원소가 같은 트리에 있음을 자명하게 알 수 있다.</p>
</li>
<li><p>위의 연산을 구현하기 위해서 자식 노드들이 부모 노드의 정보를 알고 있어야 한다.</p>
<ul>
<li>하지만, 부모 노드는 자식 노드에게 갈 일이 없기 때문에 자식 노드에 대한 정보를 저장할 필요가 없다.</li>
<li>또, 루트는 그 부모가 없으므로, 자기 자신을 부모로 지정한다.</li>
</ul>
</li>
</ul>
<h4 id="시간복잡도">시간복잡도</h4>
<ul>
<li>find()의 시간 복잡도는 대상이 되는 트리의 높이에 비례하는 시간이 걸린다.</li>
<li>집합(트리)을 합치는 uni()함수의 시간복잡도 또한 find가 지배하기 때문에, 이 역시 트리의 높이에 비례한다.</li>
</ul>
<h2 id="--최적화-경로-압축-최적화">- 최적화 (경로 압축 최적화)</h2>
<blockquote>
<p>find(u)를 통해서, 찾아낸 u가 속한 트리의 루트를 parent[u]에 반영한다면, 다음에 find(u)가 호출되었을 때, 경로를 찾아갈 필요 없이 빠르게 루트를 찾을 수 있다.</p>
</blockquote>
<hr>
<h1 id="예제--boj-1717-집합의-표현">예제 : boj 1717 집합의 표현</h1>
<p><a href="https://www.acmicpc.net/problem/1717">https://www.acmicpc.net/problem/1717</a></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;

int n, m;
int u, a, b;
int parent[1000001];

int find(int node){ // 같은 집합인지 확인 (같은 뿌리인지 확인)
    if(parent[node] == node) return node; // 뿌리 노드일 경우 본인 리턴
    else return parent[node] = find(parent[node]); // 경로 압축 최적화
}

void uni(int a, int b){ // 합집합 (a 집합을 b 집합의 자식노드로 합침)
    int rootA = find(a);
    int rootB = find(b);

    parent[rootA] = rootB;
}

void init(){ // 부모 배열 초기화
    for(int i=0;i&lt;=n;i++){
        parent[i] = i;
    }
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; n &gt;&gt; m;

    init();

    for(int i=0;i&lt;m;i++){
        cin &gt;&gt; u &gt;&gt; a &gt;&gt; b;

        if(u == 0){
            uni(a,b);
        }
        if(u == 1){ 
            if(find(a) == find(b)) cout &lt;&lt; &quot;YES&quot; &lt;&lt; &quot;\n&quot;;
            else cout &lt;&lt; &quot;NO&quot; &lt;&lt; &quot;\n&quot;;
        }
    }

    return 0;
}</code></pre>
<hr>
<h4 id="reference">Reference</h4>
<p><a href="https://velog.io/@kasterra/%EB%AA%85%EC%98%88-STL-union-find-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0">https://velog.io/@kasterra/%EB%AA%85%EC%98%88-STL-union-find-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (g2) 12015 가장 긴 증가하는 부분 수열2]]></title>
            <link>https://velog.io/@peanut_/boj-g2-12015-%EA%B0%80%EC%9E%A5-%EA%B8%B4-%EC%A6%9D%EA%B0%80%ED%95%98%EB%8A%94-%EB%B6%80%EB%B6%84-%EC%88%98%EC%97%B42</link>
            <guid>https://velog.io/@peanut_/boj-g2-12015-%EA%B0%80%EC%9E%A5-%EA%B8%B4-%EC%A6%9D%EA%B0%80%ED%95%98%EB%8A%94-%EB%B6%80%EB%B6%84-%EC%88%98%EC%97%B42</guid>
            <pubDate>Mon, 16 Jan 2023 03:58:15 GMT</pubDate>
            <description><![CDATA[<p>✅ 이분탐색 ✅ lower_bound</p>
<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/12015">https://www.acmicpc.net/problem/12015</a></p>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>dp로 풀면 시간 복잡도가 n제곱이 나오는데 이 문제는 n의 최댓값이 1,000,000이므로 n제곱으로 풀면 시간초과가 난다.
👉 이분탐색</p>
</blockquote>
<p>dp를 통해 가장 긴 증가하는 부분 수열을 푸는 문제도 있으니 풀어보도록 하자.
<a href="https://www.acmicpc.net/problem/11053">[boj] (s2) 11053 가장 긴 증가하는 부분 수열</a></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;

int N, ans=1;
int arr[1000001];
vector&lt;int&gt; permutation;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N;

    for(int i=0;i&lt;N;i++){
        cin &gt;&gt; arr[i];
    }

    permutation.push_back(arr[0]);
    for(int i=1;i&lt;N;i++){
        if(arr[i] &gt; permutation.back()){
            permutation.push_back(arr[i]);
        }
        else{
            // arr[i] 보다 크나 같은 값이 처음으로 나타나는 위치에 넣음 (대치)
            int idx = lower_bound(permutation.begin(), permutation.end(), arr[i]) - permutation.begin();
            permutation[idx] = arr[i];
        }
    }

    cout &lt;&lt; permutation.size() &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 징검다리]]></title>
            <link>https://velog.io/@peanut_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A7%95%EA%B2%80%EB%8B%A4%EB%A6%AC</link>
            <guid>https://velog.io/@peanut_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A7%95%EA%B2%80%EB%8B%A4%EB%A6%AC</guid>
            <pubDate>Thu, 12 Jan 2023 06:04:11 GMT</pubDate>
            <description><![CDATA[<p>✅ 이분탐색</p>
<h1 id="문제">문제</h1>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/43236">https://school.programmers.co.kr/learn/courses/30/lessons/43236</a></p>
<h1 id="풀이">풀이</h1>
<p><a href="https://mjmjmj98.tistory.com/78">https://mjmjmj98.tistory.com/78</a></p>
<blockquote>
<p>n개의 바위를 빼보며 모든 경우의 수를 따져보기에는 시간초과가 남.
바위 사이의 최소 거리 중 최대 값을 이분탐색으로 가능한지 따져 찾음</p>
</blockquote>
<p>이전에 풀었던 <a href="https://velog.io/@peanut_/boj-g4-2110-%EA%B3%B5%EC%9C%A0%EA%B8%B0-%EC%84%A4%EC%B9%98">[boj] (g4) 2110 공유기 설치</a> 와 흡사한 문제</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

bool isPossible(int distance, vector&lt;int&gt; rocks, int n, int min_dist){

    int prev = 0; // 시작점
    int cnt = 0; // 제거할 바위의 수

    for(int i=0;i&lt;rocks.size();i++){
        if(rocks[i] - prev &lt; min_dist){ // 바위 제거
            cnt ++;
        }
        else prev = rocks[i];
    }
    if(distance - prev &lt; min_dist) cnt++;

    if(cnt &lt;= n) return true;

    return false;
}

int solution(int distance, vector&lt;int&gt; rocks, int n) {
    int answer;

    sort(rocks.begin(), rocks.end());

    int low = 0, high = distance;
    while(low &lt;= high){
        int mid = (low + high)/2;

        if(isPossible(distance, rocks, n, mid)){
            answer = mid;
            low = mid + 1;
        }
        else high = mid - 1;
    }

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (g4) 2110 공유기 설치]]></title>
            <link>https://velog.io/@peanut_/boj-g4-2110-%EA%B3%B5%EC%9C%A0%EA%B8%B0-%EC%84%A4%EC%B9%98</link>
            <guid>https://velog.io/@peanut_/boj-g4-2110-%EA%B3%B5%EC%9C%A0%EA%B8%B0-%EC%84%A4%EC%B9%98</guid>
            <pubDate>Thu, 12 Jan 2023 02:08:24 GMT</pubDate>
            <description><![CDATA[<p>✅ 이분탐색</p>
<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/2110">https://www.acmicpc.net/problem/2110</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>집의 개수 N이 최대 200,000 개 이므로 모든 경우의 수를 세어서 구할 수 없음 O(200,000^2)
-&gt; 이분탐색을 통해 가장 인접한 두 공유기 사이의 거리를 최대로 갖는 사이 거리를 찾을 수 있음</p>
</blockquote>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;

int N, C, ans = 0;
int house[200001];

bool isPossible(int dist){ // dist : 가장 인접한 두 공유기 사이의 거리

    int cnt = 1; // 첫번째 집에 공유기 설치하고 시작
    int prev = house[0];

    for(int i=1;i&lt;N;i++){
        if(house[i]-prev &gt;= dist){ // 가장 인접한 두 공유기 사이의 거리의 최댓값이 dist가 되어야 하므로 dist 보다 멀리 떨어져 있는 경우에만 공유기 설치
            cnt ++;
            prev = house[i];
        }
    }

    if(cnt &gt;= C) return true;

    return false;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N &gt;&gt; C;

    for(int i=0;i&lt;N;i++){
        cin &gt;&gt; house[i];
    }

    sort(house, house + N);

    int low = 1, high = house[N-1] - house[0]; // 인접한 두 공유기 사이 거리 범위는 1 ~ (첫째 집에서 마지막 집까지의 거리)
    while(low &lt;= high){
        int mid = (low + high)/2;

        if(isPossible(mid)) {
            ans = mid;
            low = mid + 1;
        }
        else high = mid - 1;
    }

    cout &lt;&lt; ans &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 입국심사]]></title>
            <link>https://velog.io/@peanut_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%85%EA%B5%AD%EC%8B%AC%EC%82%AC</link>
            <guid>https://velog.io/@peanut_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%85%EA%B5%AD%EC%8B%AC%EC%82%AC</guid>
            <pubDate>Wed, 11 Jan 2023 12:22:59 GMT</pubDate>
            <description><![CDATA[<p>✅ 이분탐색</p>
<h1 id="문제">문제</h1>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/43238">https://school.programmers.co.kr/learn/courses/30/lessons/43238</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<p><a href="https://0xd00d00.github.io/2021/06/29/programmers_entry_test.html">https://0xd00d00.github.io/2021/06/29/programmers_entry_test.html</a></p>
<blockquote>
<p>각 심사대는 동시에 심사를 하기 때문에 실제 심사처럼 생각하면 계산하기 복잡하다.
동시에 심사를 하기 때문에 인당 몇분이 걸리는지가 아니라, 각 심사대가 1분에 몇명 심사를 하는지 계산하면
각 심사대는 동시에 심사하여 총 n 명을 심사하는데 얼마나 걸리는지 계산하기 편함</p>
</blockquote>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

long long solution(int n, vector&lt;int&gt; times) {
    long long answer = 0;

    long long low = 1;
    long long high = n*((long long)*max_element(times.begin(), times.end())); // 주의 : vector는 int형이므로 형변환을 해줘야 함

    while(low &lt;= high){
        long long mid = (low+high)/2;

        long long people = 0; // 심사를 마친 사람의 수
        for(int i=0;i&lt;times.size();i++){
            people += mid/times[i];
        }

        if(n &lt;= people) {
            answer = mid;
            high = mid - 1;
        }
        else low = mid + 1;
    }

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s2) 10971 외판원 순회 2]]></title>
            <link>https://velog.io/@peanut_/boj-s2-10971-%EC%99%B8%ED%8C%90%EC%9B%90-%EC%88%9C%ED%9A%8C-2</link>
            <guid>https://velog.io/@peanut_/boj-s2-10971-%EC%99%B8%ED%8C%90%EC%9B%90-%EC%88%9C%ED%9A%8C-2</guid>
            <pubDate>Wed, 11 Jan 2023 09:57:36 GMT</pubDate>
            <description><![CDATA[<p>✅ 브루트포스 ✅ dfs</p>
<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/10971">https://www.acmicpc.net/problem/10971</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>N이 최대 10이므로 모든 도시를 가보는 경우의 수는 N을 일렬로 세우는 방법의 수와 같으므로 최대 10! 이다.
즉, 모든 경우를 다 가보고 최소 비용을 출력하면 됨 -&gt; 완탐 -&gt; dfs</p>
</blockquote>
<ul>
<li>주의 : 시작점으로 돌아가야 하기 때문에 시작점으로 돌아가는 비용도 더해줘야 한다.</li>
</ul>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;

int N;
int W[11][11];
bool visited[11];
int ans=2e9; // 비용
int start_city; // 출발 도시

void dfs(int node, int cnt_visited, int cnt){
    if(cnt_visited == N) { // 모든 도시 방문했을 경우
        if(W[node][start_city] &gt; 0) ans = min(ans, cnt+W[node][start_city]); // 시작점으로 돌아갈 수 있다면 비용 추가
        return;
    }

    for(int i=1;i&lt;=N;i++){
        if(W[node][i] == 0) continue;
        if(visited[i]) continue;

        visited[i] = true;
        dfs(i, cnt_visited+1, cnt + W[node][i]);
        visited[i] = false;
    }
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N;

    for(int i=1;i&lt;=N;i++){
        for(int j=1;j&lt;=N;j++){
            cin &gt;&gt; W[i][j];
        }
    }

    for(int i=1;i&lt;=N;i++){ // 시작도시
        start_city = i;

        visited[i] = true;
        dfs(i, 1, 0);
        visited[i] = false;
    }

    cout &lt;&lt; ans &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s2) 1654 랜선 자르기]]></title>
            <link>https://velog.io/@peanut_/boj-s2-1654-%EB%9E%9C%EC%84%A0-%EC%9E%90%EB%A5%B4%EA%B8%B0</link>
            <guid>https://velog.io/@peanut_/boj-s2-1654-%EB%9E%9C%EC%84%A0-%EC%9E%90%EB%A5%B4%EA%B8%B0</guid>
            <pubDate>Wed, 11 Jan 2023 03:17:36 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/1654">https://www.acmicpc.net/problem/1654</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>K &lt;= N &lt;= 1,000,000
K는 10,000 이하이기 때문에 모든 K개의 랜선을 잘라가며 총 N개를 만들 수 있는 길이를 찾으려면
1,000,000 x 10,000 = 10,000,000,000 -&gt; 시간초과
👉 따라서 _<strong>이분탐색</strong>_으로 찾아보자.</p>
</blockquote>
<p>랜선의 길이는 231-1보다 작거나 같은 자연수이기 때문에 랜선의 길이를 갖는 변수는 long long형을 사용해야 한다.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;

int K, N;
long long cable[10001];
long long low = 1, high = 0, ans;

int Cnt_cable(long long size){
    int sum = 0;
    for(int i=0;i&lt;K;i++){
        sum += cable[i]/size;
    }

    return sum;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; K &gt;&gt; N;

    for(int i=0;i&lt;K;i++){
        cin &gt;&gt; cable[i];
        high = max(high, cable[i]);
    }

    while(low &lt;= high){
        long long mid = (low + high)/2;

        if(Cnt_cable(mid) &gt;= N) {
            low = mid + 1;
            ans = mid;
        }
        else high = mid - 1;
    }

    cout &lt;&lt; ans &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s3) 1072 게임]]></title>
            <link>https://velog.io/@peanut_/boj-s3-1072-%EA%B2%8C%EC%9E%84</link>
            <guid>https://velog.io/@peanut_/boj-s3-1072-%EA%B2%8C%EC%9E%84</guid>
            <pubDate>Mon, 09 Jan 2023 09:00:45 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/1072">https://www.acmicpc.net/problem/1072</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>1 ≤ X ≤ 1,000,000,000 이므로 승률(Z)이 변하는 값을 선형탐색하여 찾으려면 시간초과가 남
따라서 <strong>이진탐색</strong> 이용</p>
</blockquote>
<ul>
<li>long long 형 사용</li>
<li>주의 : 99%는 아무리 해도 100%가 되지 못한다.</li>
</ul>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;

long long X, Y, Z;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; X &gt;&gt; Y;

    Z = Y*100/X;

    if(Z &gt;= 99){ // 99%는 아무리 해도 100%가 되지 못한다.
        cout &lt;&lt; -1 &lt;&lt; &quot;\n&quot;;
        return 0;
    }

    long long left=0, right=1000000000, ans;
    while(left &lt;= right){
        long long mid = (left + right)/2;

        long long win_per = (Y+mid)*100/(X+mid);
        if(win_per &lt;= Z) left = mid + 1;
        else {
            ans = mid;
            right = mid - 1;
        }
    }

    cout &lt;&lt; ans &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s3) 2512 예산]]></title>
            <link>https://velog.io/@peanut_/boj-s3-2512-%EC%98%88%EC%82%B0-u3yarfv4</link>
            <guid>https://velog.io/@peanut_/boj-s3-2512-%EC%98%88%EC%82%B0-u3yarfv4</guid>
            <pubDate>Sat, 07 Jan 2023 04:40:19 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/2512">https://www.acmicpc.net/problem/2512</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<ul>
<li>배정된 예산들 중 최댓값은 상한액일 수도, 요청한 예산을 모두 줄 수 있어 그중 최댓값일 수도 있다.</li>
<li>따라서 요청한 예산의 최솟값 ~ 최댓값 안에 구하고자 하는 값이 있는데, 구하고자 하는 값이 요청한 예산들을 모두 만족하는지 확인해야 한다.</li>
<li>완전탐색으로 풀게되면 요청 예산의 수 (지방의 수) N은 3 이상 10,000 이하이므로 최악의 경우 10,000 x 10,000 = 1억이므로 시간초과가 날 수 있다.</li>
</ul>
<blockquote>
<p>따라서 _<strong>이분 탐색</strong>_을 통해 범위를 반씩 줄여가며 탐색한다.</p>
</blockquote>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;

int N, M;
int arr[100001];
int high, low = 0, ans;

bool isPossible(int mid){
    int sum = 0;

    for(int i=0;i&lt;N;i++){
        if(arr[i] &lt; mid) sum += arr[i];
        else sum += mid;
    }

    if(sum &lt;= M) return true;

    return false;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N;
    for(int i=0;i&lt;N;i++){
        cin &gt;&gt; arr[i];
        high = max(high, arr[i]);
    }
    cin &gt;&gt; M;

    while(low &lt;= high){
        int mid = (low + high)/2;

        if(isPossible(mid)) {
            ans = mid;
            low = mid + 1;
        }
        else high = mid - 1;
    }

    cout &lt;&lt; ans &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s3) 2559 수열]]></title>
            <link>https://velog.io/@peanut_/boj-s3-2559-%EC%88%98%EC%97%B4</link>
            <guid>https://velog.io/@peanut_/boj-s3-2559-%EC%88%98%EC%97%B4</guid>
            <pubDate>Fri, 06 Jan 2023 06:35:37 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/2559">https://www.acmicpc.net/problem/2559</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
#include &lt;string&gt;

using namespace std;

int N, K;
int arr[100002];
int pSum[100002];
vector&lt;int&gt; temp;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N &gt;&gt; K;

    for(int i=1;i&lt;=N;i++){
        cin &gt;&gt; arr[i];

        pSum[i] = pSum[i-1] + arr[i];
    }

    for(int i=1;i&lt;=N-(K-1);i++){
        temp.push_back(pSum[i+K-1]-pSum[i-1]);
    }

    cout &lt;&lt; *max_element(temp.begin(), temp.end()) &lt;&lt; &quot;\n&quot;;


    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (g4) 2015 수들의 합 4]]></title>
            <link>https://velog.io/@peanut_/boj-g4-2015-%EC%88%98%EB%93%A4%EC%9D%98-%ED%95%A9-4</link>
            <guid>https://velog.io/@peanut_/boj-g4-2015-%EC%88%98%EB%93%A4%EC%9D%98-%ED%95%A9-4</guid>
            <pubDate>Fri, 06 Jan 2023 06:34:20 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/2015">https://www.acmicpc.net/problem/2015</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<p>시간초과 때문에 <strong>누적합</strong>과 <strong>맵</strong>을 같이 사용해야 하는 문제였다. (+ <strong>long long</strong> 사용)</p>
<blockquote>
<p>부분합이 K가 되는 경우를 세야 하는데 누적합을 이용하여 부분합을 구하기 때문에
누적합 차가 K가 되는 경우를 세야 한다.
하지만 누적합 배열을 돌면서 모든 경우를 세면 시간초과가 난다.</p>
</blockquote>
<blockquote>
<p>따라서 누적합의 원소들을 맵에 저장하면서 이전에 저장한 누적합 중에 차가 K가 되는 경우가 있었다면 ans에 더해준다. </p>
</blockquote>
<p>처음에는 map에 누적합 원소들을 모두 저장해두고 차가 K가 되는 경우를 구하려고 했는데
이 경우에는 map 크기의 제곱 만큼 돌아야 하기 때문에 시간초과가 난다. (O(n^2))</p>
<p>따라서 map에 누적합 원소들을 저장하면서 동시에 이전에 저장한 차가 K가 되는 원소가 있었다면 ans에 더해주어야 한다. (O(n))</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
#include &lt;string&gt;
#include &lt;map&gt;

using namespace std;

int arr[200002];
int pSum[200002];
long long ans;

map&lt;int, int&gt; pSum_cnt;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int N, K;
    cin &gt;&gt; N &gt;&gt; K;

    for(int i=1;i&lt;=N;i++){
        cin &gt;&gt; arr[i];
        pSum[i] = pSum[i-1] + arr[i];
    }

    for(int i=1;i&lt;=N;i++){
        if(pSum[i] == K) ans++;
        if(pSum_cnt[pSum[i]-K]) ans+=pSum_cnt[pSum[i]-K];
        pSum_cnt[pSum[i]]++;
    }

    cout &lt;&lt; ans &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s2) 20438 출석체크]]></title>
            <link>https://velog.io/@peanut_/boj-s2-20438-%EC%B6%9C%EC%84%9D%EC%B2%B4%ED%81%AC</link>
            <guid>https://velog.io/@peanut_/boj-s2-20438-%EC%B6%9C%EC%84%9D%EC%B2%B4%ED%81%AC</guid>
            <pubDate>Fri, 06 Jan 2023 06:22:38 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/20438">https://www.acmicpc.net/problem/20438</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
#include &lt;string&gt;

using namespace std;

int N,K,Q,M;
int check[5004];
int pSum[5004];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N &gt;&gt; K &gt;&gt; Q &gt;&gt; M;

    for(int i=0;i&lt;K;i++){
        int n;
        cin &gt;&gt; n;
        check[n] = -1;
    }

    for(int i=0;i&lt;Q;i++){
        int n;
        cin &gt;&gt; n;

        if(check[n] == 0){
            for(int j=n;j&lt;=N+2;j+=n){
                if(check[j] != -1) check[j] = 1;
            }
        }
    }

    for(int i=3;i&lt;=N+2;i++){
        if(check[i] != 1) pSum[i] = pSum[i-1] + 1;
        else pSum[i] = pSum[i-1];
    }

    for(int i=0;i&lt;M;i++){
        int s,e;
        cin &gt;&gt; s &gt;&gt; e;
        cout &lt;&lt; pSum[e] - pSum[s-1] &lt;&lt; &quot;\n&quot;;
    }

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s1) 11660 구간 합 구하기 5]]></title>
            <link>https://velog.io/@peanut_/boj-s1-11660-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-5</link>
            <guid>https://velog.io/@peanut_/boj-s1-11660-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-5</guid>
            <pubDate>Fri, 06 Jan 2023 03:15:53 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/11660">https://www.acmicpc.net/problem/11660</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>표의 최대 크기가 1024 x 1024 이므로 매번 표 전체를 탐색하며 최대 100,000번 연산을 하면 1024 x 1024 x 100,000 번이므로 시간초과 날듯
-&gt; 누적합을 이용해 (1,1)에서 (x,y)까지의 합을 미리 구해 저장해두자
-&gt; (x1, y1)부터 (x2, y2)의 합을 구할 때는 중복 되는 부분 유의</p>
</blockquote>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
#include &lt;string&gt;

using namespace std;

int N, M;
int map[1026][1026];
int pSum_map[1026][1026]; // 누적합

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; N &gt;&gt; M;

    for(int i=1;i&lt;=N;i++){
        for(int j=1;j&lt;=N;j++){
            cin &gt;&gt; map[i][j];
            pSum_map[i][j] = pSum_map[i-1][j] + pSum_map[i][j-1] - pSum_map[i-1][j-1] + map[i][j];
        }
    }

    for(int i=0;i&lt;M;i++){
        int x1, y1, x2, y2;
        cin &gt;&gt; x1 &gt;&gt; y1 &gt;&gt; x2 &gt;&gt; y2;
        cout &lt;&lt; pSum_map[x2][y2] - pSum_map[x1-1][y2] - pSum_map[x2][y1-1] + pSum_map[x1-1][y1-1] &lt;&lt; &quot;\n&quot;;
    }

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s1) 16139 인간-컴퓨터 상호작용]]></title>
            <link>https://velog.io/@peanut_/boj-s1-16139-%EC%9D%B8%EA%B0%84-%EC%BB%B4%ED%93%A8%ED%84%B0-%EC%83%81%ED%98%B8%EC%9E%91%EC%9A%A9</link>
            <guid>https://velog.io/@peanut_/boj-s1-16139-%EC%9D%B8%EA%B0%84-%EC%BB%B4%ED%93%A8%ED%84%B0-%EC%83%81%ED%98%B8%EC%9E%91%EC%9A%A9</guid>
            <pubDate>Wed, 04 Jan 2023 08:28:37 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/16139">https://www.acmicpc.net/problem/16139</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>문자열의 길이가 최대 20만이고 문제의 수도 최대 20만개이다.
따라서 단순 반복문으로 특정 문자의 개수를 매번 구하면 20만 x 20만 이므로 시간초과가 날 수 있다.
👉 _<strong>누적합</strong>_을 이용하여 문자열 각 문자 갯수의 누적합을 미리 구해놓자.</p>
</blockquote>
<p>누적합을 구하기 위해
문자열을 한번 돌면서 알파벳이 나올때 이차배열(누적합 배열)을 1로 미리 저장해놓고
그 다음, 누적합을 구해 이차배열(누적합 배열)을 완성해야 한다.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
#include &lt;string&gt;

using namespace std;

string s;
int q;
int sum_s[26][200001]; // 문자열 s의 알파벳 별 누적합

void CountAlp(){
    // 알파벳 나올 때 1로 저장
    for(int i=0;i&lt;s.size();i++){
        sum_s[s[i]-&#39;a&#39;][i] = 1; 
    }

    // 누적합 만듦
    for(int i=1;i&lt;s.size();i++){
        for(int j=0;j&lt;26;j++){
            if(sum_s[j][i] == 1) sum_s[j][i] = sum_s[j][i-1] + 1;
            else sum_s[j][i] = sum_s[j][i-1];
        }
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin &gt;&gt; s;
    CountAlp();

    cin &gt;&gt; q;
    for(int i=0;i&lt;q;i++){
        char ch;
        int l, r;
        cin &gt;&gt; ch &gt;&gt; l &gt;&gt; r;

        if(l == 0){
            cout &lt;&lt; sum_s[ch-&#39;a&#39;][r] &lt;&lt; &quot;\n&quot;;
        }
        else{
            cout &lt;&lt; sum_s[ch-&#39;a&#39;][r] - sum_s[ch-&#39;a&#39;][l-1] &lt;&lt; &quot;\n&quot;;
        }
    }

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[boj] (s3) 11659 구간 합 구하기 4]]></title>
            <link>https://velog.io/@peanut_/boj-s3-11659-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-4</link>
            <guid>https://velog.io/@peanut_/boj-s3-11659-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-4</guid>
            <pubDate>Tue, 03 Jan 2023 04:11:13 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://www.acmicpc.net/problem/11659">https://www.acmicpc.net/problem/11659</a></p>
<hr>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>수의 개수 N과 합을 구해야 하는 횟수 M이 최대 100,000 이므로
단순 반복문으로 풀면 100,000 * 100,000으로 시간초과
👉 구간합 이용</p>
</blockquote>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;

int N, M;
vector&lt;int&gt; arr;
vector&lt;int&gt; s; // 구간합

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);


    cin &gt;&gt; N &gt;&gt; M;
    for(int i=0;i&lt;N;i++){
        int num;
        cin &gt;&gt; num;
        arr.push_back(num);

        if(i==0)s.push_back(num);
        if(i&gt;=1)s.push_back(num + s[i-1]);
    }

    for(int i=0;i&lt;M;i++){
        int x,y;
        cin &gt;&gt; x &gt;&gt; y;
        cout &lt;&lt; s[y-1] - s[x-2] &lt;&lt; &quot;\n&quot;;
    }

    return 0;
}</code></pre>
]]></description>
        </item>
    </channel>
</rss>