<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>#include &lt;zohee&gt;</title>
        <link>https://velog.io/</link>
        <description>Juhee Kim | Game Client Developer</description>
        <lastBuildDate>Fri, 18 Aug 2023 12:51:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>#include &lt;zohee&gt;</title>
            <url>https://velog.velcdn.com/images/slow_cosmos/profile/08d468b3-22d3-4fbd-ba57-94f2f191bc3f/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. #include &lt;zohee&gt;. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/slow_cosmos" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[c++/백준] 2565번: 전깃줄*]]></title>
            <link>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-2565%EB%B2%88-%EC%A0%84%EA%B9%83%EC%A4%84</link>
            <guid>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-2565%EB%B2%88-%EC%A0%84%EA%B9%83%EC%A4%84</guid>
            <pubDate>Fri, 18 Aug 2023 12:51:00 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/266e19de-564d-4110-a8eb-0ff4452b0101/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://www.acmicpc.net/problem/2565">2565번: 전깃줄</a></p>
<h3 id="풀이">풀이</h3>
<p><code>LIS(최장 증가 부분 수열)</code>을 이용하는 <code>DP</code>문제</p>
<ol>
<li>먼저 첫번째 전깃줄을 기준으로 오름차순 정렬을 한다.</li>
<li>정렬된 전깃줄의 두번째 전깃줄 배열의 최장 증가 부분 수열을 구한다.
2-1. 이 수열이 겹치지 않는 전깃줄의 최대수가 될테니 <code>n</code>에서 빼주면 답이 나온다.
2-2. 입력값이 크지 않기 때문에 <code>O(n^2)</code>의 <code>dp</code>로 푼다. 현재 전깃줄의 <code>dp</code>를 <code>1</code>로 초기화해준 뒤, 이전 전깃줄보다 현재 전깃줄이 크다면 <code>dp</code> 값을 비교해 갱신한다.</li>
<li>그렇게 <code>dp</code>의 최대값을 구해 <code>n</code>에서 빼면 된다.</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
using namespace std;

int main()
{
    int n;
    cin &gt;&gt; n;

    vector&lt;vector&lt;int&gt;&gt; v(n, vector&lt;int&gt;(2));
    for (int i = 0; i &lt; n; i++)
    {
        cin &gt;&gt; v[i][0] &gt;&gt; v[i][1];
    }
    sort(v.begin(), v.end());

    vector&lt;int&gt; dp(n);
    int remove = 0;
    for (int i = 0; i &lt; n; i++) // 현재 
    {
        dp[i] = 1;
        for (int j = 0; j &lt; i; j++) // 이전
        {
            if (v[j][1] &lt; v[i][1])
            {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        remove = max(remove, dp[i]);
    }

    cout&lt;&lt;n-remove&lt;&lt;endl;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/백준] 3273번: 두 수의 합]]></title>
            <link>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-3273%EB%B2%88-%EB%91%90-%EC%88%98%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-3273%EB%B2%88-%EB%91%90-%EC%88%98%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Fri, 18 Aug 2023 03:38:26 GMT</pubDate>
            <description><![CDATA[<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://www.acmicpc.net/problem/3273">3273번: 두 수의 합</a></p>
<h3 id="풀이">풀이</h3>
<ol>
<li>서로 다른 정수이기 때문에 투포인터로 풀면 된다. </li>
<li>오름차순 정렬 후 왼쪽 포인터, 오른쪽 포인터로 나누어서
2-1. 같으면 <code>answer++</code> 후, <code>left++</code>, <code>right++</code> 해준다.
2-2. 크다면 <code>right--</code>, 작다면 <code>left++</code> 해준다.</li>
<li>왼쪽 포인터가 오른쪽 포인터보다 같거나 커질 때까지 해준다.</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
using namespace std;

int main()
{
    int answer = 0;
    int n, k;
    cin &gt;&gt; n;
    vector&lt;int&gt; v(n);
    for (int i = 0; i &lt; n; i++)
    {
        cin &gt;&gt; v[i];
    }
    cin &gt;&gt; k;

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

    int left = 0;
    int right = n - 1;
    while (left &lt; right)
    {
        if (v[left] + v[right] == k)
        {
            answer++;
            left++;
            right--;
        }
        else if (v[left] + v[right] &gt; k)
        {
            right--;
        }
        else
        {
            left++;
        }
    }

    cout &lt;&lt; answer &lt;&lt; endl;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/프로그래머스] 합승 택시 요금]]></title>
            <link>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%95%A9%EC%8A%B9-%ED%83%9D%EC%8B%9C-%EC%9A%94%EA%B8%88</link>
            <guid>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%95%A9%EC%8A%B9-%ED%83%9D%EC%8B%9C-%EC%9A%94%EA%B8%88</guid>
            <pubDate>Wed, 09 Aug 2023 04:42:46 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/6076024a-68a7-4b99-8521-0511270b2c91/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/72413">합승 택시 요금</a></p>
<h3 id="풀이">풀이</h3>
<p>다익스트라로 푸는 문제. 시간 초과 날 것 같았는데 안나네 ..</p>
<ol>
<li>먼저 인접리스트를 초기화한다.</li>
<li>시작 노드부터 다익스트라로 최단 거리를 계산한다.
2-1. <code>dijkstra</code> 함수를 만들어 계산하였다. 모든 노드까지를 무한대로 두고 (나 같은 경우, 노드가 최대 200개, 요금은 최대 100,000이므로 20,000,000 이상은 안나올 것이라 생각해 정의해주었다) 우선 순위 큐를 이용해 최단 노드를 계속 갱신해준다.</li>
<li>여기가 핵심 알고리즘인데, 2번까지 해서 최단 경로가 있는 벡터가 반환될 텐데, 바로 <code>[a]</code>와 <code>[b]</code>를 더해주면 처음부터 각자 가는 것이다.
3-1. 노드를 다 돌면서 시작 노드부터 해당 노드까지는 같이 가고, 해당 노드부터 <code>a</code>와 <code>b</code>까지는 각자 가는 것으로 다시 <code>dijkstra</code>를 구해준다.</li>
<li>모든 루트를 다 돌면서 제일 적은 금액이 최소 금액이 될 것이다.</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;queue&gt;
#define INF 20000000

using namespace std;

vector&lt;int&gt; dijkstra(vector&lt;vector&lt;pair&lt;int,int&gt;&gt;&gt; &amp;adj, int s)
{
    vector&lt;int&gt; dist(adj.size(), INF);
    dist[s] = 0;

    priority_queue&lt;pair&lt;int,int&gt;, vector&lt;pair&lt;int,int&gt;&gt;, greater&lt;pair&lt;int,int&gt;&gt;&gt; pq;
    pq.push({0,s});
    while(!pq.empty())
    {
        int cost = pq.top().first;
        int cur = pq.top().second;
        pq.pop();
        for(int i=0;i&lt;adj[cur].size();i++)
        {
            pair&lt;int,int&gt; node = adj[cur][i];
            if(cost+node.first &lt; dist[node.second])
            {
                pq.push({node.first+cost, node.second});
                dist[node.second] = cost+node.first;
            }
        }
    }

    return dist;
}

int solution(int n, int s, int a, int b, vector&lt;vector&lt;int&gt;&gt; fares) {
    int answer = 0;

    vector&lt;vector&lt;pair&lt;int,int&gt;&gt;&gt; adj(n+1); // 인접리스트
    for(int i=0;i&lt;fares.size();i++) // 초기화
    {
        int stt = fares[i][0];
        int end = fares[i][1];
        int cost = fares[i][2];
        adj[stt].push_back({cost, end});
        adj[end].push_back({cost, stt});
    }

    vector&lt;int&gt; sttRoute = dijkstra(adj, s);
    answer = sttRoute[a] + sttRoute[b]; // 처음부터 각자 가는거
    for(int i=1;i&lt;=n;i++)
    {
        if(i == s) continue;

        int tmp = sttRoute[i]; // i까지는 같이 가고

        vector&lt;int&gt; tmpArr = dijkstra(adj, i);
        tmp += tmpArr[a] + tmpArr[b]; // 각자 집 따로 가기

        answer = min(answer, tmp);
    }

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/프로그래머스] 길 찾기 게임]]></title>
            <link>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B8%B8-%EC%B0%BE%EA%B8%B0-%EA%B2%8C%EC%9E%84</link>
            <guid>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B8%B8-%EC%B0%BE%EA%B8%B0-%EA%B2%8C%EC%9E%84</guid>
            <pubDate>Mon, 07 Aug 2023 08:56:54 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/4e8eedd8-98a0-4752-b7ac-7b9de774d91d/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42892">길 찾기 게임</a></p>
<h3 id="풀이">풀이</h3>
<p>이진트리를 만들고 순회하는 문제</p>
<ol>
<li>먼저 <code>Node</code> 구조체를 만들어준다.
1-1. 순회해서 인덱스를 출력해야 하므로 <code>data</code>, 위치값인 <code>x</code>, <code>y</code>, 왼쪽 자식 노드 포인터 <code>left</code>와 오른쪽 자식 노드 포인터 <code>right</code>
1-2. 처음엔 생성자를 만들어줬는데 그럴 필요 없음 ..</li>
<li><code>Node</code> 벡터를 만들어주고 초기화 해준 뒤, 정렬을 해주어야 함
2-1. <code>y</code> 값으로 내림차순 정렬, <code>x</code> 값으로 오름차순 정렬해준다. 해당 커스텀 정렬 함수는 <code>compare</code></li>
<li>정렬 후 <code>0</code>번째 노드는 제일 위에 있는 노드이므로 <code>root</code>가 된다. <code>1</code>번째 노드부터 부모에 연결해준다. 해당 함수는 <code>setParent</code>
3-1. 부모 노드 포인터인 <code>parent</code>의 <code>x</code>값이 해당 노드 <code>x</code>값 보다 크다면 왼쪽에 있다는 것. 부모의 왼쪽 자식 노드가 <code>NULL</code>이라면 해당 노드가 그 부모의 왼쪽 자식 노드가 된다. 이미 자식이 있다면 해당 왼쪽 자식 노드를 다시 부모로 재귀호출해준다. 오른쪽도 마찬가지로 진행</li>
<li>이진트리의 순회는 재귀호출로 쉽게 가능하다. 전위순회는 <code>해당노드</code>-&gt;<code>왼쪽자식</code>-&gt;<code>오른쪽자식</code>, 후위순회는 <code>왼쪽자식</code>-&gt;<code>오른쪽자식</code>-&gt;<code>해당노드</code> 순이 된다. 해당 노드일 때는 <code>data</code> 값을 넣고, 자식 노드일 때는 재귀호출 해주면 된다. 물론 <code>NULL</code> 체크도 해줘야 널 익셉션이 안뜸</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;iostream&gt;

using namespace std;

struct Node
{
    int data;
    int x, y;
    Node* left;
    Node* right;

    Node(int _data, int _x, int _y) : data(_data), x(_x), y(_y)
    {
        left = NULL;
        right = NULL;
    }
};

bool compare(Node a, Node b)
{
    if (a.y == b.y) return a.x &lt; b.x;
    else return a.y &gt; b.y;
}

void setParent(Node* parent, Node* node)
{
    if (parent-&gt;x &gt; node-&gt;x) // 왼쪽에 있음
    {
        if (parent-&gt;left == NULL)
        {
            parent-&gt;left = node;
            return;
        }
        setParent(parent-&gt;left, node);
    }
    else // 오른쪽에 있음
    {
        if (parent-&gt;right == NULL)
        {
            parent-&gt;right = node;
            return;
        }
        setParent(parent-&gt;right, node);
    }
}

void preorder(Node* root, vector&lt;int&gt; &amp;pre)
{
    pre.push_back(root-&gt;data);
    if(root-&gt;left != NULL) preorder(root-&gt;left, pre);
    if(root-&gt;right != NULL) preorder(root-&gt;right, pre);
}

void postorder(Node* root, vector&lt;int&gt; &amp;post)
{
    if(root-&gt;left != NULL) postorder(root-&gt;left, post);
    if(root-&gt;right != NULL) postorder(root-&gt;right, post);
    post.push_back(root-&gt;data);
}

vector&lt;vector&lt;int&gt;&gt; solution(vector&lt;vector&lt;int&gt;&gt; nodeinfo) {
    vector&lt;vector&lt;int&gt;&gt; answer;

    vector&lt;Node&gt; tree;
    for (int i = 0; i &lt; nodeinfo.size(); i++)
    {
        tree.push_back({ i + 1, nodeinfo[i][0], nodeinfo[i][1] }); // x,y,인덱스
    }

    sort(tree.begin(), tree.end(), compare); // y 내림차순, x 오름차순 정렬

    Node* root = &amp;tree[0]; // 루트 노드
    for (int i = 1; i &lt; tree.size(); i++) // 트리 만들어주기
    {
        setParent(root, &amp;tree[i]);
    }

    vector&lt;int&gt; answer1;
    preorder(root, answer1);

    vector&lt;int&gt; answer2;
    postorder(root, answer2);

    answer.push_back(answer1);
    answer.push_back(answer2);

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/프로그래머스] 택배상자]]></title>
            <link>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%83%9D%EB%B0%B0%EC%83%81%EC%9E%90</link>
            <guid>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%83%9D%EB%B0%B0%EC%83%81%EC%9E%90</guid>
            <pubDate>Sat, 05 Aug 2023 07:02:19 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/62517452-9134-47b2-9f43-b57feafddc0a/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/131704">택배상자</a></p>
<h3 id="풀이">풀이</h3>
<p><code>stack</code>과 <code>queue</code> 문제</p>
<ol>
<li>메인 컨테이너는 <code>queue</code>이고, 서브 컨테이너는 <code>stack</code>이다. 먼저 <code>queue</code>인 <code>main</code>에 초기화를 해준다.</li>
<li>주문을 보면서 <code>main</code>의 맨 앞 상자가 주문 상자보다 작거나 같다면 주문한 상자가 메인 컨테이너에 있다는 것이므로 찾을 때까지 <code>pop</code>한다. 이 때 메인 컨테이너가 비어있지 않아야 에러가 안뜬다.
2-1. 상자가 같다면 <code>answer++</code>해주고 break</li>
<li>2번 조건이 아니라면 상자는 서브에 있다는 것. 서브 컨테이너에서는 더이상 옮길 곳이 없으므로 <code>sub.top()</code>이 주문한 상자가 아니라면 바로 break
3-1. 마찬가지로 같다면 <code>answer++</code>해주고 서브 컨테이너에서 <code>pop</code>해준다.</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;queue&gt;
#include &lt;stack&gt;

using namespace std;

int solution(vector&lt;int&gt; order) {
    int answer = 0;

    queue&lt;int&gt; main;
    stack&lt;int&gt; sub;

    for(int i=1;i&lt;=order.size();i++) // 메인 컨테이너 초기화
    {
        main.push(i);
    }

    for(int i=0;i&lt;order.size();i++)
    {
        if(!main.empty() &amp;&amp; main.front() &lt;= order[i]) // 상자가 메인 컨테이너에 있다면
        {
            while(1)
            {
                int front = main.front();

                main.pop();
                if(front == order[i])
                {
                    answer++;
                    break;
                }
                sub.push(front);
            }
        }
        else // 상자가 서브 컨테이너에 있다면
        {
            if(sub.top() == order[i])
            {
                answer++;
                sub.pop();
            }
            else
            {
                break;
            }
        }
    }


    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/프로그래머스] [1차] 프렌즈4블록]]></title>
            <link>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-1%EC%B0%A8-%ED%94%84%EB%A0%8C%EC%A6%884%EB%B8%94%EB%A1%9D</link>
            <guid>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-1%EC%B0%A8-%ED%94%84%EB%A0%8C%EC%A6%884%EB%B8%94%EB%A1%9D</guid>
            <pubDate>Fri, 04 Aug 2023 08:33:37 GMT</pubDate>
            <description><![CDATA[<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/17679#">[1차] 프렌즈4블록</a></p>
<h3 id="풀이">풀이</h3>
<p>테케 5번만 안풀리길래 뭐지 했는데 <code>checkBoard</code>에서 빈 칸일 때 continue 해줘야하는 걸, break 함..ㅋㅋ</p>
<ol>
<li>먼저 <code>v</code>에 초기화 해주고, while문을 돌려서 <code>checkBoard</code>가 <code>true</code>일 때 계속 반복해준다.</li>
<li><code>checkBoard</code>는 터질 블럭이 있는지 체크하는 함수
2-1. 보드를 돌려보며 인덱스를 기준으로 오른쪽, 아래, 오른쪽 대각선 아래가 같은지 체크해서 같으면 터질 블럭으로 간주하고 <code>set</code>인 <code>erase</code>에 추가한다. (중복 블럭이 있을 수 있으니 바로 지우면 안됨)
2-2. 빈칸으로 네 개가 다 같아도 터질 블럭이라 간주하면 while문이 평생 안끝날 수도 있으니 빈 칸이면 continue 해준다.</li>
<li><code>eraseBlock</code>은 블럭을 지우고 위에 있는 블럭들을 내리는 함수
3-1. <code>erase</code>를 돌면서 <code>answer++</code>해주고, 빈 칸으로 만들어준다.
3-2. 위에 행부터 밑으로 가면서 체크하는데, 방문하는 블럭 밑 칸이 빈칸일 경우 반복문을 통해 해당 블럭부터 0행까지 쫙 다 내려오게 한다. 내려오는 중에 빈칸인 블럭이 나온다면 위에도 빈칸이니까 바로 break</li>
<li><code>erase</code>는 참조로 했기 때문에 <code>clear</code>를 잊지 않도록 한다.</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;set&gt;

using namespace std;
int answer = 0;

void eraseBlock(vector&lt;vector&lt;char&gt;&gt; &amp;v, set&lt;pair&lt;int,int&gt;&gt; &amp;erase)
{
    for(auto u:erase) // 지워질 블럭 &#39;0&#39;으로 체크
    {
        answer++;
        v[u.first][u.second] = &#39;0&#39;;
    }

    for(int i=0;i&lt;v.size()-1;i++)
    {
        for(int j=0;j&lt;v[i].size();j++)
        {
            if(v[i+1][j] == &#39;0&#39;) // 밑에 있는게 지워질 블럭이라면
            {
                for(int k=i;k&gt;=0;k--)
                {
                    if(v[k][j] == &#39;0&#39;) break;
                    v[k+1][j] = v[k][j];
                    v[k][j]=&#39;0&#39;;
                }
            }
        }
    }
}

bool checkBoard(vector&lt;vector&lt;char&gt;&gt; &amp;v, set&lt;pair&lt;int,int&gt;&gt; &amp;erase) // 터질 블럭이 있는지 체크
{
    bool flag = false;
    for(int i=0;i&lt;v.size()-1;i++)
    {
        for(int j=0;j&lt;v[i].size()-1;j++)
        {
            if(v[i][j] == &#39;0&#39;) continue;
            if(v[i][j] == v[i][j+1] &amp;&amp; v[i][j] == v[i+1][j] &amp;&amp; v[i][j] == v[i+1][j+1])
            {
                erase.insert({i, j});
                erase.insert({i, j+1});
                erase.insert({i+1, j});
                erase.insert({i+1, j+1});
                flag = true;
            }
        }
    }
    return flag;
}

int solution(int m, int n, vector&lt;string&gt; board) {    
    vector&lt;vector&lt;char&gt;&gt; v(m, vector&lt;char&gt;(n));
    for(int i=0;i&lt;m;i++)
    {
        for(int j=0;j&lt;n;j++)
        {
            v[i][j] = board[i][j];
        }
    }

    set&lt;pair&lt;int,int&gt;&gt; erase;
    while(checkBoard(v, erase)) // 지울 블럭이 있다면
    {
        eraseBlock(v, erase); // 지우기
        erase.clear();
    }

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Unity] 타이머 구현]]></title>
            <link>https://velog.io/@slow_cosmos/Unity-%ED%83%80%EC%9D%B4%EB%A8%B8-%EA%B5%AC%ED%98%84</link>
            <guid>https://velog.io/@slow_cosmos/Unity-%ED%83%80%EC%9D%B4%EB%A8%B8-%EA%B5%AC%ED%98%84</guid>
            <pubDate>Fri, 21 Jul 2023 06:02:20 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/2f5b17bb-574b-4299-9c4d-7b8d3fc9c296/image.gif" alt=""><img src="https://velog.velcdn.com/images/slow_cosmos/post/41ff36f3-418a-46b8-b834-4a2a3642a861/image.gif" alt=""></p>
<h3 id="두가지-형태의-타이머-구현">두가지 형태의 타이머 구현</h3>
<p>타이쿤 개발하면서 손님들의 개별 타이머와 전체 타이머를 구현했다.
개별 타이머는 바 형식, 전체 타이머는 숫자로 표현함
모두 코루틴을 이용하여 구현하였다.</p>
<h3 id="숫자-형식의-타이머-tostring-format">숫자 형식의 타이머 (ToString Format)</h3>
<p>처음에 00:00 포맷으로 어떻게 만들지 했는데 <code>ToStrnig</code>으로 포맷 지정을 할 수 있었다.
<code>minute.ToString(&quot;00&quot;)</code> 형식으로 지정하면 알아서 포맷에 맞게 바꾸어줌</p>
<pre><code class="language-cs">using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class Timer : MonoBehaviour
{
    [SerializeField] private TMP_Text text;

    [SerializeField] private float time;
    [SerializeField] private float curTime;

    int minute;
    int second;

    private void Awake()
    {
        time = 70;
        StartCoroutine(StartTimer());
    }

    IEnumerator StartTimer()
    {
        curTime = time;
        while(curTime &gt; 0)
        {
            curTime -= Time.deltaTime;
            minute = (int)curTime / 60;
            second = (int)curTime % 60;
            text.text = minute.ToString(&quot;00&quot;) + &quot;:&quot; + second.ToString(&quot;00&quot;);
            yield return null;

            if(curTime &lt;= 0)
            {
                Debug.Log(&quot;시간 종료&quot;);
                curTime = 0;
                yield break;
            }
        }
    }
}
</code></pre>
<h3 id="바-형식의-타이머-image">바 형식의 타이머 (Image)</h3>
<p>인스펙터에서 끌어다 줄 Image는 <code>Image Type</code>을 <code>Filled</code>로 바꾸어주고 <code>Fill Method</code>를 이용해 어떤 방식으로 줄어들지 고를 수 있다. <code>Fill Amount</code>를 조절하면서 확인하면 쉬움</p>
<pre><code class="language-cs">using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CustomerTimer : MonoBehaviour
{
    [SerializeField] private Image gauge;

    private float time = 20;
    private float timeSpeed;

    private float curTime;

    public bool isEnd;

    private void Awake()
    {
        isEnd = false;
        StartCoroutine(OrderTimer());
    }

    IEnumerator OrderTimer()
    {
        curTime = time;
        while(curTime &gt; 0)
        {
            curTime -= Time.deltaTime * timeSpeed;
            gauge.fillAmount = curTime / time;
            yield return null;

            if(curTime &lt;= 0)
            {
                isEnd = true;
                curTime = 0;
                yield break;
            }
        }
    }

    public void InitTimeSpeed(float speed)
    {
        timeSpeed = speed;
    }

    public void PlusTime(float plus)
    {
        curTime += plus;
        if(curTime&gt;time)
        {
            curTime = time;
        }
    }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/프로그래머스] 숫자 변환하기]]></title>
            <link>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 13 Jun 2023 06:54:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/b4435db7-697d-47c2-ad73-6ae5eb477ec5/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/154538#">숫자 변환하기</a></p>
<h3 id="풀이">풀이</h3>
<p><code>BFS</code>를 이용하는 문제</p>
<ol>
<li><code>x</code>와 <code>y</code>가 같다면 return <code>0</code> -&gt; 이 처리를 안해줘서 하나 틀렸었음
1-1. <code>queue</code>에 <code>{x,0}</code> 값을 push, <code>x</code>는 현재 값, <code>0</code>은 연산 횟수. <code>visited[x]=1</code>도 해준다.</li>
<li><code>q</code>가 빌 때까지 반복한다.
2-1. 차례대로 <code>num+n</code>, <code>num*2</code>, <code>num*3</code>을 계산해서 계산 값이 <code>y</code>를 넘거나, 이미 방문했다면(방문했다면 그 연산횟수가 최소일테니) continue, <code>calc[i]==y</code>라면 숫자를 찾은거니  return <code>cnt+1</code></li>
<li><code>q</code>에 현재 값 push, 방문처리해준다.</li>
<li>해당 반복문이 끝나도 <code>return</code> 처리가 안되는거면 <code>y</code>를 못찾은 채 <code>y</code>를 넘어버린 것이므로 (못찾은 것이므로) return <code>-1</code></li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;queue&gt;

using namespace std;

int BFS(int x, int y, int n)
{
    queue&lt;pair&lt;int,int&gt;&gt; q;
    vector&lt;int&gt; visited(y+1);

    if(x==y) return 0; // 이미 x와 y가 같다면

    q.push({x,0});
    visited[x] = 1;

    while(!q.empty())
    {
        int num = q.front().first;
        int cnt = q.front().second;
        q.pop();

        int calc[3] = {num+n, num*2, num*3};
        for(int i=0;i&lt;3;i++)
        {
            if(calc[i]&gt;y) continue; // 계산 값이 y를 넘으면
            if(visited[calc[i]]==1) continue; // 이미 방문했던 숫자라면
            if(calc[i]==y) return cnt+1; // 찾으면 return

            q.push({calc[i],cnt+1});
            visited[calc[i]] = 1;
        }
    }

    return -1;
}

int solution(int x, int y, int n) {
    int answer = 0;

    answer = BFS(x,y,n);

    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/프로그래머스] [3차] 파일명 정렬*]]></title>
            <link>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-3%EC%B0%A8-%ED%8C%8C%EC%9D%BC%EB%AA%85-%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-3%EC%B0%A8-%ED%8C%8C%EC%9D%BC%EB%AA%85-%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Tue, 13 Jun 2023 06:12:52 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/bedd98bf-6500-48e6-a329-7c9d773d39b7/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/17686#">[3차] 파일명 정렬</a></p>
<h3 id="풀이">풀이</h3>
<p><code>문자열</code>과 <code>커스텀 정렬</code>로 푸는 문제
여기서 <code>sort</code>함수로 풀면 1,2번만 맞고 <code>stable_sort</code>로 푸니까 다 맞았다..
<strong><code>stable_sort</code>는 두 요소 간의 순서를 보장하는 함수!</strong>
예를 들어 <code>{1,5,4,5,3}</code>이라는 벡터를 정렬 할 때 <code>{1,3,4,5,5}</code>로 정렬이 될텐데 그냥 <code>sort</code>는 5 요소 두 개가 같은 값이니 순서가 보장 되지 않아 앞의 5가 뒤로 갈 수 있지만, <code>stable_sort</code>는 이 두 개의 5 순서를 보장한다.</p>
<ol>
<li>구조체로 <code>File</code>을 정의해 <code>name</code>에는 원래 파일명, <code>head</code>와 <code>number</code>에는 문제대로 넣기로 한다.</li>
<li><code>seperate</code> 함수를 이용해 파일명을 <code>head</code>와 <code>number</code>로 나눈다. <code>tail</code>은 정렬하는 데에 필요없으니 패스
2-1. <code>file[i]</code>이 숫자면 <code>numberFlag</code>를 <code>true</code>로 하고 <code>number</code> <code>string</code>에 넣어준다.
2-2. 문자인데 <code>numberFlag</code>가 <code>false</code>면 아직 <code>number</code>가 없었다는 뜻, 즉 <code>head</code>란 뜻이므로 <code>head</code>에 <code>toupper</code>로 대문자 변환해서 넣어준다. 대문자 변환을 하는 이유는 문제에서 대소문자 상관없이 처리하기 위함이다.
2-3. 문자인데 <code>numberFlag</code>가 <code>true</code>면 <code>tail</code>이라는 의미이므로 처리할 필요가 없어서<code>break</code>
2-4. 그렇게 완성된 <code>head</code>와 <code>number</code>를 구조체로 만들어 return. 정렬을 해야하기 때문에 <code>number</code>는 <code>stoi</code>로 int 형변환을 해준다.</li>
<li>이제 커스텀 정렬을 해준다. 이를 위한 함수 <code>compare</code>은 구조체 <code>File</code>로 입력을 받아서 두 개의 <code>head</code>로 오름차순 정렬, <code>head</code>가 같다면 <code>number</code>로 정렬을 해준다.</li>
<li>그렇게 정렬된 <code>arr</code>를 <code>answer</code>에 <code>name</code>만 push_back 해주면 끝.</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;

using namespace std;

struct File
{
    string name;
    string head;
    int number;
};

File seperate(string file)
{
    string head = &quot;&quot;;
    string number = &quot;&quot;;
    bool numberFlag = false;

    for(int i=0;i&lt;file.size();i++)
    {
        if(&#39;0&#39;&lt;=file[i] &amp;&amp; file[i]&lt;=&#39;9&#39;)
        {
            numberFlag = true;
            number+=file[i];
        }
        else
        {
            if(!numberFlag) head += toupper(file[i]);
            else break;
        }
    }


    File f = {file, head, stoi(number)};

    return f;
}

bool compare(File a, File b)
{
    if(a.head == b.head) return a.number &lt; b.number;
    return a.head &lt; b.head;
}

vector&lt;string&gt; solution(vector&lt;string&gt; files) {
    vector&lt;string&gt; answer;

    vector&lt;File&gt; arr;
    for(int i=0;i&lt;files.size();i++)
    {
        arr.push_back(seperate(files[i]));
    }

    stable_sort(arr.begin(), arr.end(),compare);
    for(int i=0;i&lt;arr.size();i++)
    {
        cout&lt;&lt;arr[i].head&lt;&lt;&quot; &quot;&lt;&lt;arr[i].number&lt;&lt;endl;
        answer.push_back(arr[i].name);
    }
    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/프로그래머스] 행렬의 곱셈]]></title>
            <link>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%96%89%EB%A0%AC%EC%9D%98-%EA%B3%B1%EC%85%88</link>
            <guid>https://velog.io/@slow_cosmos/c%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%96%89%EB%A0%AC%EC%9D%98-%EA%B3%B1%EC%85%88</guid>
            <pubDate>Thu, 08 Jun 2023 12:39:02 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/4cd2e08b-0952-4920-938c-dc919a59c587/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/12949">행렬의 곱셈</a></p>
<h3 id="풀이">풀이</h3>
<p>행렬의 곱셈을 통해 2(행) X 3(열), 3 X 5 =&gt; 2 X 5의 행렬이 만들어짐 (첫번째 행렬의 열과 두번째 행렬의 행은 크기가 같아야 함)</p>
<p>이 행렬에서 (1,2)값을 구하고 싶다면? (0부터 시작하는 인덱스)
<code>[1][0]*[0][2] + [1][1]*[1][2] + [1][2]*[2][2]</code></p>
<ol>
<li><code>arr1</code>의 행이 <code>i</code>개, 열이 <code>k</code>개, <code>arr2</code>의 행이 <code>k</code>개, 열이 <code>j</code>개 일 때 행렬의 곱셈 결과는 <code>i</code>의 행과 <code>j</code>의 열이 만들어진다. 그렇게 <code>answer</code>의 사이즈를 미리 정해둔다.</li>
<li>하나 하나씩 계산을 해준다.
2-1. <code>arr1[i][k]*arr2[k][k]</code>값을 모두 더해주면 <code>answer[i][j]</code>의 값이 나온다</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

vector&lt;vector&lt;int&gt;&gt; solution(vector&lt;vector&lt;int&gt;&gt; arr1, vector&lt;vector&lt;int&gt;&gt; arr2) {
    vector&lt;vector&lt;int&gt;&gt; answer(arr1.size(), vector&lt;int&gt;(arr2[0].size()));

    for(int i=0;i&lt;answer.size();i++) // 행
    {
        for(int j=0;j&lt;answer[i].size();j++) // 열
        {
            int tmp = 0;
            for(int k=0;k&lt;arr2.size();k++)
            {
                tmp += arr1[i][k] * arr2[k][j];
            }
            answer[i][j] = tmp;
        }
    }
    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/백준] 1091번: 카드 섞기]]></title>
            <link>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-1091%EB%B2%88-%EC%B9%B4%EB%93%9C-%EC%84%9E%EA%B8%B0</link>
            <guid>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-1091%EB%B2%88-%EC%B9%B4%EB%93%9C-%EC%84%9E%EA%B8%B0</guid>
            <pubDate>Thu, 08 Jun 2023 10:50:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/23c2a3a6-5b69-409f-807b-3810660e86cb/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://www.acmicpc.net/problem/1091">1091번: 카드 섞기</a></p>
<h3 id="풀이">풀이</h3>
<p>문제 해석을 잘못해서 조금 헤맸던 문제</p>
<ol>
<li><code>Shake()</code>함수에서 카드를 섞도록 한다.
1-1. <code>tmp[S[i]] = arr[i];</code>
1-2. 한 번 섞을 때마다 <code>answer++</code></li>
<li>섞인 카드가 원하는 대로 가는지 확인하는 함수 <code>Check()</code>
2-1. <code>P[arr[i]] != i%3</code> 일 경우는 제대로 주어지지 않는다는 뜻이므로 <code>false</code> 리턴</li>
<li><code>Check()</code>가 <code>true</code> 될 때까지 <code>Shake()</code> 하는데,
3-1. 이미 한 번 나온 카드 순서(<code>arr</code>)가 또 나올 경우, 계속 해도 원하는 카드의 순서가 안나온다는 의미
3-2. 이 것의 체크는 <code>set</code>으로 한다.
3-3. <code>set</code>에 있으면 <code>-1</code> 리턴, 없으면 <code>set</code>에 insert</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;set&gt;

using namespace std;

int n;
vector&lt;int&gt; P;
vector&lt;int&gt; S;
vector&lt;int&gt; arr;
int answer = 0;

set&lt;vector&lt;int&gt;&gt; order;

bool Check()
{
    for (int i = 0; i &lt; n; i++)
    {
        if (P[arr[i]] != i%3) return false;
    }
    return true;
}

void Shake()
{    
    if (Check())
    {
        cout &lt;&lt; answer &lt;&lt; endl;
        return;
    }

    vector&lt;int&gt; tmp(n);
    for (int i = 0; i &lt; n; i++) // 섞기
    {
        tmp[S[i]] = arr[i];
    }
    arr = tmp;

    if (order.find(arr) != order.end()) // 이미 검사한 카드 순서라면
    {
        cout &lt;&lt; -1 &lt;&lt; endl;
        return;
    }
    order.insert(arr);

    answer++;

    Shake();
}

int main(void)
{
    cin &gt;&gt; n;

    P.resize(n);
    S.resize(n);

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

    arr.resize(n);
    for (int i = 0; i &lt; n; i++)
    {
        arr[i] = i;
    }

    Shake();

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/해커랭크] Find the Point]]></title>
            <link>https://velog.io/@slow_cosmos/c%ED%95%B4%EC%BB%A4%EB%9E%AD%ED%81%AC-Find-the-Point</link>
            <guid>https://velog.io/@slow_cosmos/c%ED%95%B4%EC%BB%A4%EB%9E%AD%ED%81%AC-Find-the-Point</guid>
            <pubDate>Tue, 30 May 2023 12:46:16 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/e7aa7c38-0099-4e61-b8d2-71c8d4883fb1/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://www.hackerrank.com/challenges/find-point/problem?isFullScreen=true">Find the Point</a></p>
<h3 id="풀이">풀이</h3>
<p><code>p</code>와 <code>q</code>의 입력을 받고 <code>q</code>를 기준으로 <code>p</code>를 180도 회전하는 문제
<code>q</code>값에 <code>q</code>와 <code>p</code>의 차이를 더해주면 됨</p>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">vector&lt;int&gt; findPoint(int px, int py, int qx, int qy) {
    vector&lt;int&gt; result;

    result.push_back(qx+qx-px);
    result.push_back(qy+qy-py);

    return result;
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/백준] 1439번: 뒤집기]]></title>
            <link>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-1439%EB%B2%88-%EB%92%A4%EC%A7%91%EA%B8%B0</link>
            <guid>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-1439%EB%B2%88-%EB%92%A4%EC%A7%91%EA%B8%B0</guid>
            <pubDate>Fri, 19 May 2023 07:35:36 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/fc888b47-0b12-4894-8a36-7e61c751788b/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://www.acmicpc.net/problem/14390">1439번: 뒤집기</a></p>
<h3 id="풀이">풀이</h3>
<ol>
<li>먼저 0의 구역 개수와 1의 구역 개수를 세는 <code>fCnt</code>, <code>tCnt</code></li>
<li>맨 처음 글자에 따라 영역 시작 개수를 센다.</li>
<li>그 다음 글자부터 끝까지 체크를 하는데, 현재 글자가 이전 글자(영역) <code>c</code>와 다를 경우 구역이 나누어지기 때문에 해당 글자의 영역 개수를 추가하고 이전 글자(영역) <code>c</code>를 갱신한다.</li>
<li>그렇게 만들어진 <code>fCnt</code>와 <code>tCnt</code> 값 중 작은 값을 출력 </li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

int main()
{
    string s=&quot;&quot;;
    cin &gt;&gt; s;

    int fCnt = 0;
    int tCnt = 0;

    char c = s[0];
    if (c == &#39;0&#39;)
    {
        fCnt++;
    }
    else
    {
        tCnt++;
    }

    for (int i = 1; i &lt; s.size(); i++)
    {
        if (s[i] != c)
        {
            if (s[i] == &#39;0&#39;) fCnt++;
            else tCnt++;
            c = s[i];
        }
    }

    int answer = fCnt &gt; tCnt ? tCnt : fCnt;
    cout &lt;&lt; answer &lt;&lt; endl;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/백준] 10162번: 전자레인지]]></title>
            <link>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-10162%EB%B2%88-%EC%A0%84%EC%9E%90%EB%A0%88%EC%9D%B8%EC%A7%80</link>
            <guid>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-10162%EB%B2%88-%EC%A0%84%EC%9E%90%EB%A0%88%EC%9D%B8%EC%A7%80</guid>
            <pubDate>Fri, 19 May 2023 07:23:17 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/cc0c644a-04ab-456a-a249-9cdb3cd123c2/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://www.acmicpc.net/problem/10162">10162번: 전자레인지</a></p>
<h3 id="풀이">풀이</h3>
<ol>
<li>먼저 <code>a</code>, <code>b</code>, <code>c</code>를 초단위 변환 후 <code>c</code>로도 안나누어지면 못 만드는 시간이므로 <code>-1</code> 출력</li>
<li><code>a</code>부터 차례대로 나누어 <code>Cnt</code>에 넣는다. <code>t</code>는 계속해서 갱신한다</li>
<li><code>cnt</code>를 출력</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{
    int t;
    cin &gt;&gt; t;

    int a = 300;
    int b = 60;
    int c = 10;

    int aCnt = 0;
    int bCnt = 0;
    int cCnt = 0;

    if (t%c != 0) cout &lt;&lt; -1 &lt;&lt; endl;
    else
    {
        aCnt = t / a;
        t %= a;
        bCnt = t / b;
        t %= b;
        cCnt = t / c;
        t %= c;

        cout &lt;&lt; aCnt &lt;&lt; &quot; &quot; &lt;&lt; bCnt &lt;&lt; &quot; &quot; &lt;&lt; cCnt &lt;&lt; endl;
    }
    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++] 상속의 이해]]></title>
            <link>https://velog.io/@slow_cosmos/c-%EC%83%81%EC%86%8D%EC%9D%98-%EC%9D%B4%ED%95%B4</link>
            <guid>https://velog.io/@slow_cosmos/c-%EC%83%81%EC%86%8D%EC%9D%98-%EC%9D%B4%ED%95%B4</guid>
            <pubDate>Wed, 10 May 2023 12:19:19 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/67c274c1-2c40-43f0-ab2c-b64bd5d8b0bf/image.png" alt=""></p>
<h3 id="컨트롤-클래스-핸들러-클래스">컨트롤 클래스 (핸들러 클래스)</h3>
<p>기능의 처리를 실제로 담당하는 클래스</p>
<p>기능 제공의 핵심이 되기 때문에 모든 객체지향 프로그램에서 반드시 존재하는 클래스</p>
<h3 id="상속을-사용하는-이유">상속을 사용하는 이유</h3>
<p>데이터가 담긴 클래스와 그것을 관리하는 핸들러 클래스.
데이터가 담긴 클래스의 종류가 많아질 경우 핸들러 클래스에서 변경할 부분이 많아짐
→ 확장성이 떨어짐
하지만, 상속을 사용하면 핸들러 클래스에서 변경이 거의 없어짐</p>
<h3 id="상속의-방법과-결과">상속의 방법과 결과</h3>
<pre><code class="language-cpp">class UnivStudent : public Person
{
    ...
}</code></pre>
<p>UnivStudent 클래스가 Person 클래스를 상속
→ UnivStudent 객체에는 UnivStudent 클래스에 선언된 멤버, Person 클래스에 선언되어 있는 멤버 존재</p>
<p><strong>상속의 대상이 되는 클래스의 멤버까지도 객체 내에 존재</strong></p>
<h3 id="상속받은-클래스의-생성자-정의">상속받은 클래스의 생성자 정의</h3>
<ul>
<li><strong>상속받은 클래스에서는 상속한 클래스의 초기화할 의무를 가짐</strong></li>
<li>상속받은 클래스의 생성자에서 상속한 클래스의 생성자를 호출하는 형태로 초기화</li>
</ul>
<pre><code class="language-cpp">UnivStudent(char* myname, int myage, char *mymajor)
    : Person(myname, myage)
{
    ...
}</code></pre>
<p><strong>이니셜라이저</strong>를 이용해 상속하는 클래스의 생성자 호출</p>
<h3 id="상속에-대한-접근제한">상속에 대한 접근제한</h3>
<p>접근제한의 기준은 클래스
→ 상속 받은 클래스에서 상속하는 클래스의 private 선언 멤버에 접근 불가</p>
<p>정보의 은닉은 하나의 객체 내에서도 진행</p>
<h3 id="상속-용어의-정리">상속 용어의 정리</h3>
<p>상위 클래스 ↔ 하위 클래스
기초(base) 클래스 ↔ 유도(derived) 클래스
슈퍼(super) 클래스 ↔ 서브(sub) 클래스
부모 클래스 ↔ 자식 클래스</p>
<h3 id="✨-유도-클래스의-객체-생성과정">✨ 유도 클래스의 객체 생성과정</h3>
<ul>
<li><strong>유도 클래스의 객체생성 과정에서 기초 클래스의 생성자는 100% 호출</strong></li>
<li>유도 클래스의 생성자에서 기초 클래스의 생성자 호출을 명시하지 않으면, <strong>기초 클래스의 void 생성자 호출</strong></li>
</ul>
<p><code>class SoDerived : public SoBase</code></p>
<p><code>SoDerived dr3(23,24);</code></p>
<ol>
<li>메모리 공간 할당</li>
<li><code>SoDerived</code>의 생성자 호출</li>
<li>상속하는 것을 확인 후, 이니셜라이저 확인 → 기초 클래스 생성자 호출</li>
<li>해당하는 기초 클래스 생성자 호출이 완료되면 기초 클래스 멤버변수 초기화</li>
<li>유도 클래스의 생성자 실행 완료되며, 유도 클래스 멤버변수 초기화</li>
</ol>
<p><code>SoDerived dr1;</code></p>
<ol>
<li>메모리 공간 할당</li>
<li><code>SoDerived</code>의 생성자 호출</li>
<li>상속하는 것을 확인 후, 이니셜라이저 명시 X</li>
<li>기초 클래스의 void 생성자를 대신 호출, 기초 클래스 멤버변수 초기화</li>
<li>유도 클래스의 나머지 부분 실행 완료</li>
</ol>
<p><strong>클래스의 멤버는 해당 클래스의 생성자를 통해 초기화</strong></p>
<h3 id="유도-클래스-객체의-소멸과정">유도 클래스 객체의 소멸과정</h3>
<ul>
<li><strong>유도 클래스의 객체가 소멸될 때는, 유도 클래스의 소멸자가 실행되고 난 다음에 기초 클래스의 소멸자 실행</strong></li>
<li>스택에 생성된 객체의 소멸순서는 생성순서와 반대</li>
</ul>
<p>→ <strong>생성자에서 동적 할당한 메모리 공간은 소멸자에서 해제</strong></p>
<h3 id="protected-선언">protected 선언</h3>
<p>접근의 범위 : private &lt; protected &lt; pulic</p>
<p>protected로 선언된 멤버변수는 이를 상속하는 유도 클래스에서 접근 가능</p>
<p>기초 클래스와 유도 클래스 사이에서도 &#39;정보은닉&#39;은 지켜지는게 좋음</p>
<h3 id="세가지-형태의-상속">세가지 형태의 상속</h3>
<pre><code class="language-cpp">class Derived : public Base // public 상속
{
    ...
}</code></pre>
<pre><code class="language-cpp">class Derived : protected Base // protected 상속
{
    ...
}</code></pre>
<pre><code class="language-cpp">class Derived : private Base // private 상속
{
    ...
}</code></pre>
<p>protected 상속 : protected보다 접근의 범위가 넓은 멤버는 protected로 변경시켜 상속
private 상속 : private 상속을 다시 상속할 경우, 의미 없는 상속이 됨
public 상속 : private을 제외한 나머지는 그냥 그대로 상속</p>
<h3 id="상속을-위한-조건">상속을 위한 조건</h3>
<p>상속을 위한 기본 조건 : IS-A 관계의 성립</p>
<ul>
<li>무선 전화기 is a 전화기</li>
<li>노트북 컴퓨터 is a 컴퓨터</li>
</ul>
<p>HAS-A 관계도 상속의 조건은 되지만 복합 관계로 이를 대신하는 것이 일반적</p>
<p>상속으로 묶인 두 개의 클래스는 강한 연관성을 띔</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++] friend와 static 그리고 const]]></title>
            <link>https://velog.io/@slow_cosmos/c-friend%EC%99%80-static-%EA%B7%B8%EB%A6%AC%EA%B3%A0-const</link>
            <guid>https://velog.io/@slow_cosmos/c-friend%EC%99%80-static-%EA%B7%B8%EB%A6%AC%EA%B3%A0-const</guid>
            <pubDate>Mon, 08 May 2023 13:47:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/f0cd4f21-f5e0-4f07-bb54-cd4b9117437d/image.png" alt=""></p>
<h3 id="const-객체">const 객체</h3>
<p><code>const SoSimple sim(20);</code>
객체의 상수화 : 이 객체를 대상으로는 const 멤버 함수만 호출 가능</p>
<p>const의 유무도 함수 오버로딩의 조건에 해당이 됨
<code>void SimpleFunc() {...}</code>
<code>void SimpleFunc() const {...}</code></p>
<p>매개변수로 const 참조자로 받으면, const 멤버 함수를 호출</p>
<h3 id="클래스와-함수에-대한-friend-선언">클래스와 함수에 대한 friend 선언</h3>
<ul>
<li>A 클래스가 B 클래스를 대상으로 friend 선언 시, B 클래스는 A 클래스의 private 멤버에 접근 가능</li>
<li>A 클래스도 B 클래스의 private 멤버에 직접 접근 가능하려면, B 클래스도 A 클래스 대상으로 friend 선언을 해야 함</li>
</ul>
<pre><code class="language-cpp">class Boy
{
private:
    int height;
    friend class Girl; // Girl 클래스에서 Boy 클래스 멤버 변수 접근 가능
public:
    Boy(int len) : height(len)
    { }
    ....
}</code></pre>
<p><code>friend class Girl;</code> 의미</p>
<ul>
<li>Girl은 클래스의 이름이다 → 위에서 미리 선언하지 않아도 됨</li>
<li>바로 그 Girl 클래스를 friend로 선언</li>
</ul>
<p>정보은닉을 무너뜨리기 때문에 되도록 사용하지 않고, 거의 연산자 오버로딩에서 사용됨</p>
<p>함수의 friend 선언 : 전역 함수와 클래스의 멤버함수를 대상으로 friend 선언 가능</p>
<h3 id="c에서의-static">C++에서의 static</h3>
<p>static의 개념</p>
<ul>
<li>전역변수에 선언된 static의 의미 : 선언된 파일 내에서만 참조를 허용하겠다는 의미</li>
<li>함수 내에 선언된 static의 의미 : 한번만 초기화되고, 지역변수와 달리 함수를 빠져나가도 소멸되지 않음</li>
</ul>
<p>전역변수 사용 시 필요 없는 접근이 있을 수 있으므로 → <strong>클래스 내에 static 멤버로 선언</strong></p>
<p>static 멤버변수(클래스 변수)
일반 멤버변수와 달리 <strong>클래스당 하나씩만 생성</strong>
→ 메모리 공간에 딱 하나만 할당 되어 공유됨,
객체 안에 존재하는 것이 아닌, 객체에게 멤버변수처럼 접근할 수 있는 권한을 준 것</p>
<p>static 변수를 생성자에서 초기화하면 안 되는 이유 :
<strong>객체가 생성될 때 생성되는 변수가 아니라, 이미 메모리 공간에 할당이 이뤄진 변수</strong>이기 때문
<code>int SoSimple::simObjCnt=0;</code>과 같이 초기화
→ SoSimple 클래스의 static 멤버변수 simObjCnt가 메모리 공간에 저장될 때 0으로 초기화하라는 뜻</p>
<p>static 멤버변수의 또 다른 접근방법
static 멤버가 private 선언 : 해당 클래스의 객체들만 접근 가능
static 멤버가 public 선언 : 클래스의 이름, 객체의 이름을 통해 어디서든 접근 가능</p>
<p>static 멤버함수</p>
<ul>
<li>선언된 클래스의 모든 객체가 공유</li>
<li>public 선언 시, 클래스의 이름을 이용해 호출 가능</li>
<li>객체의 멤버로 존재하는 것이 아님</li>
<li><strong>static 멤버함수 내에서는 static 멤버변수와 static 멤버함수만 호출 가능</strong></li>
</ul>
<h3 id="const-static-멤버">const static 멤버</h3>
<p>클래스 내에 선언된 const 멤버변수(상수)의 초기화는 이니셜라이저를 통해야만 가능.
but, const static으로 선언되는 멤버변수(상수)는 선언과 동시에 초기화 가능
<code>const static int RUSSIA = 1707540;</code></p>
<p>const static 멤버변수는, 클래스가 정의될 때 지정된 값이 유지되는 상수</p>
<h3 id="키워드-mutable">키워드 mutable</h3>
<p>const 함수 내에서 값의 변경을 예외적으로 허용</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++] 복사 생성자]]></title>
            <link>https://velog.io/@slow_cosmos/c-%EB%B3%B5%EC%82%AC-%EC%83%9D%EC%84%B1%EC%9E%90</link>
            <guid>https://velog.io/@slow_cosmos/c-%EB%B3%B5%EC%82%AC-%EC%83%9D%EC%84%B1%EC%9E%90</guid>
            <pubDate>Sat, 06 May 2023 08:16:54 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/e4224dd1-0092-400a-b813-ad4ad7cb621b/image.png" alt=""></p>
<h3 id="c-스타일의-초기화">C++ 스타일의 초기화</h3>
<p>C++의 선언과 초기화는
<code>int num=20;</code> <code>int &amp;ref=num;</code>
도 가능하고
<code>int num(20);</code> <code>int &amp;ref(num);</code>
도 가능함</p>
<p>마찬가지로
<code>SoSimple sim2=sim1;</code> 는
<code>SoSimple sim2(sim1);</code>과 같음
<code>sim2</code> 객체를 새로 생성해, 객체 <code>sim1</code>과 <code>sim2</code>간의 멤버 대 멤버 복사가 일어남</p>
<h3 id="복사-생성자">복사 생성자</h3>
<p>C++의 모든 객체는 생성자의 호출을 동반하므로,
위 문장에서 <code>sim1</code>을 인자로 받을 수 있는 생성자의 호출을 통해 객체생성을 완료함
→ 이것이 <strong>복사 생성자</strong></p>
<pre><code class="language-cpp">SoSimple(SoSimple &amp;copy)
{
     ...
}</code></pre>
<p><code>SoSimple sim2=sim1;</code> → <code>SoSimple sim2(sim1);</code>
으로 묵시적 변환이 되어 객체 생성</p>
<p><code>복사 생성자</code>의 이름은 생성자가 호출되는 시점이 다른 일반 생성자와 차이가 있기 때문에 붙음</p>
<pre><code class="language-cpp">SoSimple(const SoSimple &amp;copy)
{
     ...
}</code></pre>
<p>이렇게 const 키워드를 삽입해 원본이 변경되는 것을 막는 것이 좋다
(이것이 일반적인 복사 생성자)</p>
<h3 id="디폴트-복사-생성자">디폴트 복사 생성자</h3>
<p>복사 생성자를 정의하지 않으면, 멤버 대 멤버의 복사를 진행하는 <strong>디폴트 복사 생성자</strong>가 자동 삽입</p>
<p>복사 생성자를 반드시 정의해야 하는 경우가 있음</p>
<h3 id="키워드-explicit">키워드 explicit</h3>
<p>복사 생성자의 묵시적 호출을 허용하지 않는 키워드 explicit</p>
<p><code>SoSimple sim2=sim1;</code>을 <code>SoSimple sim2(sim1);</code>로 변환시키지 않음
→ 대입 연산자를 이용한 객체 생성 및 초기화 불가능</p>
<pre><code class="language-cpp">explicit SoSimple(const SoSimple &amp;copy) : num1(copy.num1), num2(copy.num2)
{
    ...
}</code></pre>
<p>전달인자가 하나인 생성자에도 explicit 선언하면, 묵시적 변환을 허용하지 않음
ex) <code>AAA obj=3</code> 불가능, <code>AAA obj(3)</code>으로만 가능</p>
<h3 id="깊은-복사와-얕은-복사">깊은 복사와 얕은 복사</h3>
<p>디폴트 복사 생성자는 멤버 대 멤버의 복사를 진행 → 얕은 복사
이는 <strong>멤버변수가 힙의 메모리 공간을 참조하는 경우</strong>에 문제가 생김</p>
<p>디폴트 복사 생성자의 문제점 : 동적 할당으로 멤버변수를 정의 했다면(<code>char *</code>과 같은), 디폴트 복사 생성자로 멤버 대 멤버 복사를 진행 했을 때 주소를 복사하기 때문에, <strong>하나의 문자열을 두 개의 객체가 동시에 참조</strong>함
한 객체의 소멸자에서 delete 연산을 하고, 다른 객체의 소멸자에서도 delete 연산을 하면 이미 지워진 문자열을 대상으로 delete 연산을 하기 때문에 문제 발생
<img src="https://velog.velcdn.com/images/slow_cosmos/post/7ab80415-960b-41e6-8d27-1fb18d1ed370/image.png" alt=""></p>
<h3 id="깊은-복사를-위한-복사-생성자의-정의">깊은 복사를 위한 복사 생성자의 정의</h3>
<p>객체 별로 각각의 문자열을 참조하게 만들면 소멸과정에서 문제가 발생하지 않음
→ 멤버뿐만 아니라 포인터로 참조하는 대상까지 깊게 복사 : <strong>깊은 복사</strong></p>
<pre><code class="language-cpp">Person(const Person&amp; copy) : age(copy.age)
{
    name = new char[strlne(copy.name)+1];
    strcpy(name, copy.name);
}</code></pre>
<p>→ 이 생성자가 하는 일</p>
<ul>
<li>멤버변수 age의 멤버 대 멤버 복사</li>
<li>메모리 공간 할당 후 문자열 복사, 할당된 메모리 주소 값 멤버 name 저장</li>
</ul>
<h3 id="복사-생성자의-호출-시점">복사 생성자의 호출 시점</h3>
<ul>
<li>case 1 : 기존에 생성된 객체를 이용해 새로운 객체를 초기화 하는 경우</li>
<li>case 2 : Call by value 방식의 함수호출 과정에서 객체를 인자로 전달하는 경우</li>
<li>case 3 : 객체를 반환하되, 참조형으로 반환하지 않는 경우</li>
</ul>
<p>메모리 공간의 할당과 초기화가 동시에 일어나는 상황 :
<code>int num1=num2;</code>
→ num1이라는 메모리 공간을 할당과 동시에 num2에 저장된 값으로 초기화</p>
<pre><code class="language-cpp">int SimpleFunc(int n)
{
    ....
}
int main(void)
{
    int num=10;
    SimpleFunc(num);
}</code></pre>
<p>→ 매개변수 n이 할당과 동시에 변수 num에 저장된 값으로 초기화</p>
<pre><code class="language-cpp">int SimpleFunc(int n)
{
    ...
    return n;
}
int main(void)
{
    int num=10;
    cout&lt;&lt;SimpleFunc(num)&lt;&lt;endl;
    ...
}</code></pre>
<p>→ 반환하는 순간 메모리 공간이 할당되면서 동시에 반환 값으로 초기화
변수에 저장하는 것과 별개로, 값을 반환하면 반환된 값은 별도의 메모리 공간이 할당되어 저장 됨</p>
<p>이는 객체도 마찬가지</p>
<h3 id="할당-이후-복사-생성자를-통한-초기화">할당 이후 복사 생성자를 통한 초기화</h3>
<pre><code class="language-cpp">SoSimple SimpleFuncObj(SoSimple ob)
{
    return ob;
}</code></pre>
<p>라는 함수가 있는데
<code>SimpleFuncObj(obj);</code> 가 호출될 경우</p>
<ol>
<li>ob 객체에 obj가 전달되며 ob의 복사 생성자 호출</li>
<li>임시객체에 ob가 전달되며 임시객체의 복사 생성자 호출</li>
<li>최종적으로 반환되는 객체는 임시객체,
함수호출이 완료되면 지역적으로 선언된 객체 ob는 소멸되고 임시객체와 obj 객체만 남음</li>
</ol>
<h3 id="임시-객체">임시 객체</h3>
<p><code>Temporary(200);</code> 과 같이 값을 저장하지 않고 호출하면 임시객체 생성
임시객체가 생성된 위치에는 임시객체의 <strong>참조 값이 반환</strong>
<code>Temporary(200).ShowTempInfo();</code>이면
<code>(임시객체의 참조 값).ShowTempInfo();</code>와 같은 형태
→ 멤버함수의 호출 가능</p>
<p>참조 값이 반환되기 때문에
<code>const Temporary &amp;ref=Temporary(200);</code>의 형태도 가능(상수 참조자)</p>
<ul>
<li>임시객체는 다음 행으로 넘어가면 바로 소멸</li>
<li>참조자에 참조되는 임시객체는 바로 소멸되지는 않음</li>
</ul>
<p><code>SoSimple tempRef=SimpleFuncObj(obj);</code>
에서 SimpleFuncObj의 반환 값인 임시객체에 tempRef라는 이름을 할당해줌 (객체의 추가 생성 없이)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++] 클래스의 완성]]></title>
            <link>https://velog.io/@slow_cosmos/c-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%98-%EC%99%84%EC%84%B1</link>
            <guid>https://velog.io/@slow_cosmos/c-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%98-%EC%99%84%EC%84%B1</guid>
            <pubDate>Thu, 04 May 2023 12:14:50 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/67e4a636-8f34-46a9-83e6-f048ecfffdd3/image.png" alt=""></p>
<h3 id="정보은닉">정보은닉</h3>
<p>제한된 방법으로의 접근만 허용을 해서 잘못된 값이 저장되지 않도록 도와야 하고, 또 실수를 했을 때, 실수가 쉽게 발견되도록 해야 한다.</p>
<p>멤버변수를 <code>prive</code> 선언, 해당 변수에 접근하는 함수(엑세스 함수)를 별도로 정의
→ 안전한 형태로 변수의 접근을 유도하는 것이 바로 <code>정보은닉</code></p>
<p>엑세스 함수 : 클래스 외부에서 멤버변수 접근을 목적으로 정의되는 함수</p>
<p><code>const</code> 함수 : 이 함수 내에서는 멤버변수에 저장된 값을 변경하지 않는 것을 선언, 이 함수 내에서는 <code>const</code>가 아닌 함수의 호출이 제한
→ 코드의 안정성이 높아짐
<code>int GetX() const;</code>
<code>int GetY() const;</code>
<code>void ShowRecInfo() const;</code></p>
<h3 id="캡슐화">캡슐화</h3>
<p>하나의 목적 하에 둘 이상의 기능이 모여 하나의 목적을 달성하기 위함
관련 있는 함수와 변수를 하나의 클래스 안에 묶는 것</p>
<p>캡슐화의 범위를 결정하는 일은 쉽지 않다</p>
<p>캡슐화는 기본적으로 정보은닉을 포함하는 개념</p>
<h3 id="생성자">생성자</h3>
<p>생성자를 이용해 객체를 생성과 동시에 초기화할 수 있음</p>
<pre><code class="language-cpp">class SimpleClass
{
private:
    int num;
public:
    SimpleClass(int n) // 생성자
    {
        num=n;
    }
    int GetNum() const
    {
        return num;
    }
}</code></pre>
<p>생성자의 형태 : 클래스의 이름과 함수의 이름이 동일,
반환형이 선언되어 있지 않으며, 실제로 반환하지 않음
<strong>객체 생성시 딱 한번 호출</strong></p>
<p>객체생성과정에서 자동으로 호출되는 생성자에게 전달할 인자의 정보를 추가
<code>SimpleClass sc;</code> → <code>SimpleClass sc(20);</code>
<code>SimpleClass *ptr = new SimpleClass;</code> → <code>SimpleClass *ptr = new SimpleClass(30);</code></p>
<ul>
<li>생성자도 함수의 일종이니 오버로딩 가능</li>
<li>생성자도 함수의 일종이니 매개변수에 &#39;디폴트 값&#39; 설정 가능</li>
</ul>
<p>매개변수가 없는 생성자를 이용해 객체 생성시 <code>SimpleClass sc1;</code>과 같이 소괄호 생략
소괄호는 밑과 같은 함수의 원형선언에만 사용</p>
<pre><code class="language-cpp">SimpleClass(int n1=0, int n2=0)
{
    num1=n1;
    num2=n2;
}</code></pre>
<h3 id="멤버-이니셜라이저">멤버 이니셜라이저</h3>
<p>멤버 이니셜라이저를 이용한 멤버 초기화 : 멤버변수로 선언된 객체의 생성자 호출에 활용
<code>:upLeft(x1, y1), lowRight(x2,y2)</code> : 객체 upLeft 생성과정에서 x1과 y1을 인자로 전달받는 생성자 호출, 객체 lowRight 생성과정에서 x2와 y2를 인자로 전달 받는 생성자 호출</p>
<p>객체의 생성과정</p>
<ul>
<li>1단계 : 메모리 공간의 할당</li>
<li>2단계 : 이니셜라이저를 이용한 멤버변수(객체)의 초기화</li>
<li>3단계 : 생성자의 몸체부분 실행</li>
</ul>
<p>멤버 이니셜라이저를 이용한 변수 및 const 상수(변수) 초기화 : 객체가 아닌 멤버변수도 초기화 가능
<code>num1(n1)</code> : num1을 n1의 값으로 초기화</p>
<ul>
<li>초기화의 대상을 명확히 인식 가능</li>
<li>성능에 약간의 이점 : 선언과 동시에 초기화가 이뤄지는 형태의 바이너리 코드 생성</li>
<li><code>const</code> 변수는 선언과 동시에 초기화해야 하므로 이니셜라이저를 이용해 초기화</li>
<li>참조자도 선언과 동시에 초기화가 이뤄져야 하므로 이니셜라이저를 이용해 초기화</li>
</ul>
<h3 id="디폴트-생성자">디폴트 생성자</h3>
<p>객체가 되기 위해서는 반드시 하나의 생성자가 호출되어야 함
→ 생성자 정의가 없는 클래스에는 컴파일러에 의해 디폴트 생성자가 자동 삽입</p>
<p>디폴트 생성자는 인자를 받지 않고, 내부적으로 아무런 일도 하지 않음</p>
<p><code>AAA *ptr = new AAA;</code>와 같은 <code>new</code>를 이용한 객체 생성에도 생성자 호출
그런데,
<code>AAA *ptr = (AAA*)malloc(sizeof(AAA));</code>와 같은 <code>malloc</code> 함수호출시 생성자 호출이 안됨
<strong>객체 동적 할당시 반드시 new 연산자 이용</strong></p>
<p>매개변수가 void형으로 선언되는 디폴트 생성자는, 생성자가 하나도 정의되어 있지 않을 때만 삽입 
→ 다른 형태로 객체생성이 불가능</p>
<h3 id="private-생성자">private 생성자</h3>
<p>객체의 생성이 클래스 외부에서 진행되면 <code>public</code> 선언
객체의 생성이 클래스 내부에서 진행되면 <code>private</code> 선언</p>
<h3 id="소멸자">소멸자</h3>
<p>소멸자의 형태 : 클래스의 이름 앞에 <code>~</code>가 붙은 형태의 이름,
반환형이 선언되어 있지 않으며, 실제로 반환하지 않음,
매개변수는 void형으로 선언되어야 하기 때문에 오버로딩도, 디폴트 값 설정도 불가능
<code>~AAA() {...}</code></p>
<p>소멸자는 객체소멸 과정에서 자동으로 호출
직접 소멸자를 정의하지 않으면, 디폴트 생성자와 마찬가지로 아무런 일도 하지 않는 디폴트 소멸자 자동 삽입</p>
<p>소멸자의 사용 : 생성자에서 할당한 리소스의 소멸에 사용
ex) 생성자 내에서 new 연산자로 할당해 놓은 메모리 공간을, delete 연산자를 이용해 이 메모리 공간 소멸</p>
<h3 id="클래스와-배열">클래스와 배열</h3>
<p>객체 기반의 배열 : <code>SoSimple arr[10];</code>
동적 할당 : <code>SoSimple *ptrArr = new SoSimple[10];</code></p>
<p>배열을 선언하는 경우에도 생성자 호출이 되지만, 호출할 생성자들 별도로 명시하지 못함(생성자에 인자를 전달하지 못함)
→ <code>SoSimple() {...}</code> 의 생성자가 정의되어야 함</p>
<p>객체 포인터 배열 : 객체의 주소 값 저장이 가능한 포인터 변수로 이뤄진 배열
<code>Person * parr[3];</code></p>
<p>객체를 저장할 때는 저장의 대상을 1. 객체로 하느냐 2. 객체의 주소 값으로 하느냐 결정해야함</p>
<h3 id="this-포인터">this 포인터</h3>
<p>객체 자신을 가리키는 용도로 사용되는 포인터</p>
<pre><code class="language-cpp">SoSimple * GetThisPointer()
{
    return this;
}</code></pre>
<p>this는 객체자신의 주소 값을 의미</p>
<p>매개변수와 멤버변수의 이름이 같을 때는 <code>this</code> 포인터를 이용해 접근
<code>this-&gt;num=207;</code></p>
<p>멤버 이니셜라이저에서는 this 포인터를 사용할 수 없지만, 저장하는 변수는 멤버변수로, 저장되는 값은 매개변수로 인식하기 때문에, 그냥 써도 됨
<code>:num1(num1), num2(num2)</code></p>
<h3 id="self-reference의-반환">Self-Reference의 반환</h3>
<p>Self-Reference : 객체 자신을 참조할 수 있는 참조자</p>
<pre><code class="language-cpp">SelfRef&amp; Adder(int n)
{
    num+=n;
    return *this;
}</code></pre>
<p>객체 자신을 참조할 수 있는 참조의 정보(참조 값) 반환</p>
<p>참조의 정보(참조 값)에 대한 이해 :
<code>int num=7;</code>
<code>int &amp;ref=num;</code>
이면 참조자 <code>ref</code>에 변수 <code>num</code>을 참조할 수 있는 참조의 정보가 전달됨
대입 연산자의 왼편에 &#39;참조자의 선언&#39;이 오거나, 반환형으로 &#39;참조형&#39;이 선언되면, 그 때 전달되는 정보를 표현하기 위해 &#39;참조의 정보&#39; 또는 &#39;참조 값&#39;이라 표현</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/백준] 1004번: 어린 왕자]]></title>
            <link>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-1004%EB%B2%88-%EC%96%B4%EB%A6%B0-%EC%99%95%EC%9E%90</link>
            <guid>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-1004%EB%B2%88-%EC%96%B4%EB%A6%B0-%EC%99%95%EC%9E%90</guid>
            <pubDate>Thu, 27 Apr 2023 04:21:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/4fafd7d3-b43f-41f4-8706-d00e72e28c75/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://www.acmicpc.net/problem/1004">1004번: 어린 왕자</a></p>
<h3 id="풀이">풀이</h3>
<p><code>기하</code> 문제</p>
<ol>
<li>입력 받은 각 원마다 <code>check</code> 함수 호출</li>
<li>출발 지점과 도착 지점이 원 내부에 같이 있으면 경계를 안넘어도 되므로 return 0
2-1. 둘 중 하나만 원 내부에 있으면 경계를 넘어야 하므로 return 1
2-2. 둘 다 밖에 있을 경우도 return 0</li>
<li><code>answer</code>에 반환값을 저장해 출력한다.</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
using namespace std;

int x, y, x2, y2;

bool check(int cx, int cy, int r)
{
    if (pow(cx - x, 2) + pow(cy - y, 2) &lt;= r * r &amp;&amp; pow(cx - x2, 2) + pow(cy - y2, 2) &lt;= r * r) return 0;
    else if (pow(cx - x, 2) + pow(cy - y, 2) &lt;= r * r) return 1;
    else if (pow(cx - x2, 2) + pow(cy - y2, 2) &lt;= r * r) return 1;
    return 0;
}

int main(void)
{
    int t;
    cin &gt;&gt; t;

    for (int i = 0; i &lt; t; i++)
    {
        cin &gt;&gt; x &gt;&gt; y &gt;&gt; x2 &gt;&gt; y2;

        int n;
        cin &gt;&gt; n;

        int answer = 0;
        for (int i = 0; i &lt; n; i++)
        {
            int cx, cy, r;
            cin &gt;&gt; cx &gt;&gt; cy &gt;&gt; r;
            answer += check(cx, cy, r);
        }

        cout &lt;&lt; answer &lt;&lt; endl;
    }

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[c++/백준] 1358번: 하키]]></title>
            <link>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-1358%EB%B2%88-%ED%95%98%ED%82%A4</link>
            <guid>https://velog.io/@slow_cosmos/c%EB%B0%B1%EC%A4%80-1358%EB%B2%88-%ED%95%98%ED%82%A4</guid>
            <pubDate>Thu, 27 Apr 2023 03:53:33 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/slow_cosmos/post/f3745d13-8fac-42dc-be51-0af90304af4d/image.gif" alt=""></p>
<h3 id="문제-링크">문제 링크</h3>
<p><a href="https://www.acmicpc.net/problem/1358">1358번: 하키</a></p>
<h3 id="풀이">풀이</h3>
<p>간단한 기하 문제</p>
<ol>
<li>먼저 선수들의 위치를 입력받아 <code>check</code> 함수를 호출한다.</li>
<li><code>check</code> 함수는 각각 직사각형, 왼쪽 반원, 오른쪽 반원 내에 있는지 체크해서 return한다.
2-1. 직사각형의 왼쪽 아래 점과 오른쪽 위에 점 내부에 있으면 return
2-2. 반원은, 원 중심 좌표와 선수들의 위치 사이 거리를 계산해 반지름보다 작다면 return한다.</li>
</ol>
<h3 id="코드">코드</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
using namespace std;

int w, h, x, y;

bool check(int px, int py)
{
    if (x &lt;= px &amp;&amp; px &lt;= x + w &amp;&amp; y &lt;= py &amp;&amp; py &lt;= y + h) // 직사각형 내부
    {
        return 1;
    }
    else if (pow(x - px, 2) + pow(y + h / 2 - py, 2) &lt;= pow(h / 2, 2))
    {
        return 1;
    }
    else if (pow(x + w - px, 2) + pow(y + h / 2 - py, 2) &lt;= pow(h / 2, 2))
    {
        return 1;
    }
    return 0;
}

int main(void)
{
    int p;
    int answer = 0;
    cin &gt;&gt; w &gt;&gt; h &gt;&gt; x &gt;&gt; y &gt;&gt; p;
    for (int i = 0; i &lt; p; i++)
    {
        int px, py;
        cin &gt;&gt; px &gt;&gt; py;
        answer += check(px, py);
    }

    cout &lt;&lt; answer &lt;&lt; endl;

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