<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>nyun-nye.log</title>
        <link>https://velog.io/</link>
        <description>시야가 넓은 개발자가 되기를 희망합니다.</description>
        <lastBuildDate>Thu, 03 Apr 2025 14:59:52 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>nyun-nye.log</title>
            <url>https://velog.velcdn.com/images/nyun-nye/profile/5472e938-c0ed-4cb0-94b6-0831b345d4df/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. nyun-nye.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/nyun-nye" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[백준 - 과제(13904번)]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EA%B3%BC%EC%A0%9C13904%EB%B2%88</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EA%B3%BC%EC%A0%9C13904%EB%B2%88</guid>
            <pubDate>Thu, 03 Apr 2025 14:59:52 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/59a11b70-dd81-454c-9bd7-5edb983a2e1b/image.png" alt=""></p>
<h3 id="✏️-백준---과제13904번">✏️ <a href="https://www.acmicpc.net/problem/13904">백준 - 과제(13904번)</a></h3>
<hr/>

<p><img src="https://velog.velcdn.com/images/nyun-nye/post/c99f5e46-e898-437d-9c86-80d17c85d617/image.png" alt=""></p>
<blockquote>
<p>점수를 기준으로 내림차순 정렬을 하는 것이 포인트!</p>
</blockquote>
<br>
<br>
<br>

<h3 id="💭-코드-설계">💭 코드 설계</h3>
<hr/>
문제 해결의 단계는 아래와 같다.

<ol>
<li><code>N</code>으로 과제의 개수를 저장하고, <code>works</code> 배열에 2차원 배열로 각 과제별 마감일과 점수를 저장한다.</li>
<li><code>works</code> 배열을 점수를 기준으로 내림차순 정렬하여 <code>sortedWorks</code> 배열로 저장한다.</li>
<li><code>plan</code> 배열을 과제의 개수만큼 크기를 지정하고, 0으로 초기화한다.</li>
<li><code>sortedWorks</code> 배열에서 순서대로 가져오면서 <code>index</code>에 &quot;마감일 - 1&quot;을 저장한다. <code>plan[index]</code>의 값이 0이면 해당 <code>index</code>에 과제의 점수를 넣는다. 0이 아니라면, <code>index</code>가 0이 되거나, <code>plan[index]</code>의 값이 0일때까지 <code>index</code> 값을 줄여나간다. <code>plan[index]</code>의 값이 0이라면 과제의 점수를 넣고 <code>break</code>한다.</li>
<li><code>plan</code>에 저장된 값들을 모두 더한다.</li>
</ol>
<br>
<br>
<br>

<h3 id="🅰️-제출한-답">🅰️ 제출한 답</h3>
<hr/>

<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map((el) =&gt; el.split(&quot; &quot;));

  const N = Number(input[0][0]);
  let works = input.slice(1, N + 1).map((row) =&gt; row.map(Number));
  const sortedWorks = works.sort((a, b) =&gt; b[1] - a[1]);

  let plan = Array(N).fill(0);

  sortedWorks.forEach((work) =&gt; {
    let index = work[0]-1;
    if(plan[index] === 0){
      plan[index] = work[1];
    }else{
      while(index &gt;= 0){
        if(plan[index] === 0){
          plan[index] = work[1];
          break;
        }else{
          index--;
        }
      }
    }
  })

  console.log(plan.reduce((acc, cur) =&gt; acc+cur, 0));</code></pre>
<br>
<br>
<br>


<h3 id="💡-해설">💡 해설</h3>
<hr/>
이 문제는 위에서도 언급했듯이 <span style="background-color: yellow">과제의 점수를 내림차순 하여, 점수가 큰 과제를 마감일 전에 먼저 배정하는 것이 포인트</span>이다.<br>
고민을 조금 했던 부분 중 첫 번째는 <span style="background-color: yellow">2차원 배열로 받아오는 값들을 Number로 형변환 하는 것</span>이었다. 2차원 배열을 형 변환하기 위해서는 `map` 함수를 2번 사용하여아한다. 처음에는 `map`에서 `row`를 인자로 받아오고, 그 `row`를 다시 `map`을 이용해서 Number로 형변환 해야한다.<br>
두 번째는 과제의 마감일과 점수를 2차원 배열로 받아오기 때문에 <span style="background-color: yellow">정렬을 할때 2차원 배열 내부의 1차원 배열의 두 번째 인덱스를 기준으로 내림차순 정렬</span>을 해야한다. 이 방식을 떠올리는데 막혀서 검색을 해봤다. 허무하게도 인덱스 값에 그냥 1을 넣어주기만 하면 되는 것이었다.

<br>
<br>
<br>

<p><span style="font-weight: 600;">🤔 소감</span></br></p>
<hr>
이 문제도 골드 문제라는 이야기를 들었다. 오랜만에 문제를 풀어서 그런지 문제 푸는 것이 재밌고 오래걸리지는 않았다. 코드 구조를 구현하는 것을 금방 해냈으나, 위에서 언급한 고민했던 문법적인 부분들이 오히려 발목을 잡았다. js 문법 공부를 다시 열심히 해야겠다는 생각이 들었다.]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 3차원 막대기 연결하기]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-3%EC%B0%A8%EC%9B%90-%EB%A7%89%EB%8C%80%EA%B8%B0-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-3%EC%B0%A8%EC%9B%90-%EB%A7%89%EB%8C%80%EA%B8%B0-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 03 Apr 2025 14:35:40 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/5464e825-0c5c-48d2-b510-85af1626ae99/image.png" alt=""></p>
<h3 id="✏️-백준---3차원-막대기-연결하기19950번">✏️ <a href="https://www.acmicpc.net/problem/19950">백준 - 3차원 막대기 연결하기(19950번)</a></h3>
<hr/>

<p><img src="https://velog.velcdn.com/images/nyun-nye/post/e50fd30d-48b0-44b4-a392-6cda77180914/image.png" alt=""><img src="https://velog.velcdn.com/images/nyun-nye/post/cb98051c-09bf-41ca-928c-7b555501a40d/image.png" alt=""></p>
<blockquote>
<p>다각형의 변의 길이 조건을 적용하는 것이 포인트!</p>
</blockquote>
<br>
<br>
<br>

<h3 id="💭-코드-설계">💭 코드 설계</h3>
<hr/>
문제 해결의 단계는 아래와 같다.

<ol>
<li><code>N</code>으로 막대기 개수, <code>start</code>로 시작점, <code>end</code>로 끝점, <code>lines</code> 배열로 막대기들의 길이를 저장한다.</li>
<li>시작점과 끝 점 사이의 거리를 계산하여 <code>distance</code>에 저장한다. (피타고라스 정리를 활용한다.)</li>
<li>만약 막대기가 1개라면, <code>distance</code>와 막대기의 길이가 같아야만 한다.</li>
<li>막대기가 2개 이상이라면, <code>distance</code>를 포함한 가장 긴 변의 길이가 나머지 길이의 합보다 작거나 같아야한다. 따라서 <code>distance</code>를 <code>lines</code> 배열에 넣고, <code>max</code>에 최댓값을 저장한 다음, 최댓값을 뺀 나머지 값들의 합을 최댓값과 비교한다.</li>
</ol>
<br>
<br>
<br>

<h3 id="🅰️-제출한-답">🅰️ 제출한 답</h3>
<hr/>

<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map((el) =&gt; el.split(&quot; &quot;));

  // 막대기 1개 = 점과 점 사이의 거리(선)
  // 막대기 2개 이상: 가장 긴 변의 길이 &lt;= 나머지 길이의 합

  const N = Number(input[1][0]); // 막대기 개수

  const start = input[0].slice(0, 3).map(Number); // 시작점
  const end = input[0].slice(3, 6).map(Number); // 끝점
  const lines = input[2].map(Number); // 막대기들

  const distance = Math.sqrt((end[0] - start[0]) **2 + (end[1] - start[1])**2 + (end[2] - start[2])**2);

  if(N === 1){
    if(lines[0] === distance){
      console.log(&quot;YES&quot;);
    }else{
      console.log(&quot;NO&quot;);
    }
  } else{
    lines.push(distance);
    const max = Math.max(...lines);
    const restLines = lines.filter((line)=&gt; line !== max);
    const restSum = restLines.reduce((acc, cur) =&gt; acc+cur, 0);

    if(max &lt;= restSum){
      console.log(&quot;YES&quot;);
    }else{
      console.log(&quot;NO&quot;);
    }
  }</code></pre>
<br>
<br>
<br>

<h3 id="💡-해설">💡 해설</h3>
<hr/>
이 문제를 처음 접했을 때, 솔직히 문제가 잘 이해가 되지 않았다. 처음에는 테스트 케이스의 패턴을 분석해보려고 시도했으나 예제3에서 힌트를 얻었다.<br>
막대기가 2개라면 시작점과 끝점의 거리를 포함해서 선이 3개가 나온다. 시작점과 끝점을 이어야하므로 결국 <span style="background-color: yellow">삼각형을 만들 수 밖에 없는 구조</span>이다. 삼각형을 만들기 위한 각 변의 길이 조건은 <span style="background-color: yellow">가장 긴 변이 나머지 두 변의 합보다 작아야한다.</span> 그러나 우리는 시작점과 끝점을 잇는 것이 목표이기 때문에 나머지 두 변의 합과 가장 긴 변이 <span style="background-color: yellow">같아져도 완전히 포개어져서 가능하다.</span><br>
막대기가 3개 이상이어도 과정은 같다. 결국 가장 긴 변이 나머지의 합보다 작아져야 다각형을 만들 수 있는 구조가 되기 때문에 이와 비슷한 패턴으로 접근해서 풀었다.

<br>
<br>
<br>

<p><span style="font-weight: 600;">🤔 소감</span></br></p>
<hr>
개강을 하고 바빠서 정말 오랜만에 제대로 풀어보는 문제였다. 나는 문제의 난이도에 겁을 먹기 싫어서 난이도를 보지 않고 푼다. 이번 문제가 골드 문제라는 소리를 스터디에서 들었는데 생각보다 어렵지 않게 푼 것 같아서 뿌듯하다. 개강이라는 핑계를 대지 않고 스터디원들과 화이팅해서 문제풀이에 열중할 것이다.]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 팔(1105번)]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%ED%8C%941105%EB%B2%88</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%ED%8C%941105%EB%B2%88</guid>
            <pubDate>Mon, 03 Mar 2025 11:41:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/e2c34146-a6d1-42ee-9f7a-79f4d678fae5/image.png" alt=""></p>
<h3 id="백준---팔1105번"><a href="https://www.acmicpc.net/problem/1105">백준 - 팔(1105번)</a></h3>
<p><img src="https://velog.velcdn.com/images/nyun-nye/post/dc4ac911-2e1d-4c03-bb93-4781c498bdbb/image.png" alt=""></p>
<blockquote>
<p>자리수를 비교하는 것이 포인트인 문제이다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li><code>L</code>로 최솟값, <code>R</code>로 최댓값을 받고, 각 자리의 숫자를 비교하기 위해 string으로 변환한다.</li>
<li><code>counter</code> 변수를 통해 8의 최소 개수를 셀 것이다. 0으로 초기화한다.</li>
<li><code>L</code>과 <code>R</code>의 자리수가 다르면 0을 출력한다.</li>
<li>자리수가 같을 경우 자리수만큼 반복한다. 이때 <code>L</code>과 <code>R</code>의 각 자리의 숫자가 같으면서 그 숫자가 8이면 <code>counter</code>를 하나 증가한다. <code>L</code>과 <code>R</code>의 각 자리의 숫자가 다를경우 반복문을 종료한다.</li>
<li><code>counter</code> 값을 출력한다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(/\s+/) // \s: 공백 문자, + : 하나 이상 연속 된 경우
  .map(Number);

  const L = input[0].toString();
  const R = input[1].toString();

  let counter = 0;
  if(L.length != R.length){
    console.log(counter);
  }else{
    for(let i=0; i&lt;L.length; i++){
      if(L[i] === R[i] &amp;&amp; L[i] == 8){
        counter++;
      }else if(L[i] != R[i]){
        break;
      }
    }
    console.log(counter);
  }
</code></pre>
<hr/>

<h3 id="시행착오">시행착오</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(/\s+/) // \s: 공백 문자, + : 하나 이상 연속 된 경우
  .map(Number);

  const L = input[0].toString();
  const R = input[1].toString();

  let counter = 0;
  if(L.length != R.length){
    console.log(counter);
  }else{
    for(let i=0; i&lt;L.length; i++){
      if(L[i] != R[i])
        break;
      counter++;
    }
    console.log(counter);
  }</code></pre>
<p>처음에는 단지 자릿수 비교, 각 자리의 숫자 비교해서 같거나 다를 경우에 대해서만 코드를 작성했다. 이 경우 <code>180 189</code>와 같은 입력값이 들어왔을 때는 <code>2</code>를 출력한다. 그 이유는 8과의 비교를 놓쳤기 때문이다.</p>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
일주일 간 일본 여행을 끝내고 오랜만에 돌아와서 문제풀이를 진행중이다. 다시 열심히 공부할 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 로프(2217번)[JS]]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%A1%9C%ED%94%842217%EB%B2%88JS</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%A1%9C%ED%94%842217%EB%B2%88JS</guid>
            <pubDate>Mon, 17 Feb 2025 05:29:53 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/8b5c55d8-9f5a-4efb-b2e5-f4787e2e8775/image.png" alt=""></p>
<h3 id="백준---로프2217번"><a href="https://www.acmicpc.net/problem/2217">백준 - 로프(2217번)</a></h3>
<p><img src="https://velog.velcdn.com/images/nyun-nye/post/c895d7ec-06f8-4232-bef7-4ca66edbfc3a/image.png" alt=""></p>
<blockquote>
<p>저번에 풀었던 <a href="https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%8C%90%EB%A7%A41246%EB%B2%88-JS">백준- 온라인 판매(1246번)</a>과 비슷한 유형의 문제이다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li><code>N</code>으로 로프의 갯수를 받고, <code>rope</code> 배열에 각 로프가 버틸 수 있는 최대 중량을 저장한다.</li>
<li>로프 배열을 오름차순으로 정렬한다.</li>
<li><code>maxWeight</code> 배열을 <code>N</code>번 반복하며 각 로프의 중량에 따른 물체의 최대 중량을 저장한다.</li>
<li><code>maxWeight</code> 배열의 최댓값을 출력한다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(/\s+/) // \s: 공백 문자, + : 하나 이상 연속 된 경우
  .map(Number);

  const N = input[0];
  let rope = input.slice(1, N+1)
  rope = rope.sort((a,b)=&gt;b-a); // 오름차순
//   console.log(rope);

let maxWeight = [];

for(let i=0; i&lt;N; i++){
    // maxWeight[i] = rope[i] * (rope.filter(arg =&gt; arg &lt;= rope[i]).length);
    maxWeight[i] = rope[i] * (i+1);
}
// console.log(maxWeight);

console.log(Math.max(...maxWeight));
</code></pre>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
비슷한 유형의 문제를 한 번 풀고나니 이 문제를 푸는 것은 쉬웠다. 스터디에서 그 유형과 비슷한 문제인 것 같으니 비슷한 방식으로 풀어보는 것이 어떻냐는 의견을 참고했다. 나 혼자 풀었으면 조금 헤맸을지도..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 1로 만들기(1463번) [JS]]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-1%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B01463%EB%B2%88-JS</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-1%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B01463%EB%B2%88-JS</guid>
            <pubDate>Mon, 17 Feb 2025 05:18:46 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/e0b363d3-6afd-4273-a8f8-6cacab70727e/image.png" alt=""></p>
<h3 id="백준---1로-만들기1463번"><a href="https://www.acmicpc.net/problem/1463">백준 - 1로 만들기(1463번)</a></h3>
<p><img src="https://velog.velcdn.com/images/nyun-nye/post/793e9b42-3efb-4a72-ace2-0f0a6a02f077/image.png" alt=""></p>
<blockquote>
<p>문제는 간단하지만 푸는 방법을 고민하는 것이 어려웠다. 스스로 풀지 못하고 다른 사람들의 풀이를 참고하여 풀었다. DP 방법을 사용했다. 
동적 계획법(Dynamic Programming, DP)은 문제를 작은 하위 문제로 나누고, 그 결과를 저장하여 전체 문제를 해결하는 방법이다. 즉, 중복 계산을 줄여 효율적으로 문제를 해결하는 기법이다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li><code>N</code>으로 숫자를 입력받는다. <code>dp</code> 배열을 생성하여 <code>N</code>개만큼 0으로 초기화한다.</li>
<li>1은 이미 0으로 초기화되었으므로, 2부터 <code>N</code>까지 돌면서 연산의 최솟값을 구해 초기화한다.</li>
<li>-1을 하는 조건은 항상 실행될 수 있으므로 기본적으로 실행하여 -1을 했을때의 연산횟수와 2를 나눴을때의 연산 횟수, 3을 나눴을 때의 연산횟수를 비교하며 각 숫자의 최소 연산횟수를 배열에 채워나간다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(/\s+/)
  .map(Number);

const N = input[0];
const dp = new Array(N + 1).fill(0);

// dp[1] = 0 (이미 초기화됨)
for (let i = 2; i &lt;= N; i++) {
  dp[i] = dp[i - 1] + 1; // 항상 1을 빼는 경우 고려
  if (i % 2 === 0) dp[i] = Math.min(dp[i], dp[i / 2] + 1);
  if (i % 3 === 0) dp[i] = Math.min(dp[i], dp[i / 3] + 1);
}

console.log(dp[N]);
</code></pre>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
스스로 풀어내지 못한 첫 번째 문제라 좀 답답했다. 다른 사람들의 풀이 방식을 보니 정말 간단한 방법인데 이걸 생각해내지 못한 것이 아쉽다. 그래도 DP라는 방식에  대해서 알아보는 시간을 가진 것 같아서 의미있었다. 다음에 비슷한 문제를 풀어봐야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 온라인 판매(1246번) [JS]]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%8C%90%EB%A7%A41246%EB%B2%88-JS</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%8C%90%EB%A7%A41246%EB%B2%88-JS</guid>
            <pubDate>Tue, 11 Feb 2025 08:51:40 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/86d4f03e-dac1-4f3c-9e0e-37b199fa1180/image.png" alt=""></p>
<h3 id="백준---온라인-판매1246번"><a href="https://www.acmicpc.net/problem/1246">백준 - 온라인 판매(1246번)</a></h3>
<p><img src="https://velog.velcdn.com/images/nyun-nye/post/ec274d4c-3245-4101-9677-02e0b11f3777/image.png" alt=""></p>
<blockquote>
<p>생각보다 문제가 굉장히 까다롭고 복잡하다. 이 문제에서의 포인트는 아래 세 가지 조건이다.</p>
</blockquote>
<ol>
<li>A가격에 달걀을 판다고 하면 Pi가 A가격보다 <span style="background-color: yellow">크거나 같은</span> 모든 고객은 달걀을 산다.</li>
<li>달걀 총 수량을 초과하여 팔 수 는 없다</li>
<li>최대 수익을 올릴 수 있는 달걀의 가장 <span style="background-color: yellow">낮은 가격</span>을 책정하는 것이다</li>
</ol>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li>달걀의 개수를 <code>N</code>, 고객의 수를 <code>M</code>으로 받고, 고객이 제시한 금액은 <code>consumer</code> 배열로 받는다.</li>
<li><code>consumer</code> 배열을 <span style="background-color: yellow">오름차순</span> 정렬한다.</li>
<li><code>total</code> 배열을 초기화한다. 이 배열은 <strong>각 금액에 구매 가능한 고객의 수를 곱하여 모든 케이스의 수익</strong>을 저장한다.</li>
<li>고객의 수 만큼 반복한다.<code>counter</code>로 현재 제시된 금액보다 크거나 같은 가격의 수를 측정한다. 즉, <code>counter</code>가 해당 금액에 판매 가능한 고객의 수가 된다. 이때, <code>counter</code>의 크기가 <code>N</code>보다 작으면 <code>total</code> 배열에 0을 저장한다. 판매가 불가능 하기 때문이다.</li>
<li><code>maxTotal</code>에 <code>total</code> 배열의 최댓값 즉, 수익의 최댓값을 저장한다. <code>maxIndex</code>에 통해 해당 최댓값의 index 값을 저장하고 이를 이용하여 <code>maxPrice</code>에 달걀의 가격을 책정한다.</li>
</ol>
<p><span style="font-size: 15px;">코드 설계 2번 단계가 중요하다. 조건 3번째에서 <strong>달걀의 가장 낮은 가격</strong>을 책정한다 했다. 오름차순으로 정렬을 해야 달걀의 가격과 그 가격에 알맞은 수량을 곱해서 <code>total</code>에 저장할 경우 <code>findIndex</code> 함수는 앞에서부터 찾기 때문에 <code>max</code>값과 동일한 경우, 가격이 낮은 것을 선택할 수 있다.</span></p>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(/\s+/) // \s: 공백 문자, + : 하나 이상 연속 된 경우
  .map(Number);

  const N = input[0];
  const M = input[1];

  consumer = input.slice(2, 2+M);
  consumer = consumer.sort((a,b)=&gt;a-b);

  let total = [];

  for(let i=0; i&lt;M; i++){
    let counter = consumer.filter((arg) =&gt; arg &gt;= consumer[i]).length;
    if(counter &lt;= N)
      total[i] = consumer[i] * counter;
    else
      total[i] = 0;
  }

  const maxTotal = Math.max(...total);
  const maxIndex = total.findIndex(arg =&gt; arg===maxTotal);
  const maxPrice = consumer[maxIndex];


  console.log(maxPrice + &quot; &quot; + maxTotal);
</code></pre>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
이 문제는 생각보다 말장난이 많았던 것 같다. 얼핏 보기엔 간단해보이지만 왠지 모르게 정답을 이끌어내기가 어려웠다. 테스트 케이스가 1개밖에 없는 것도 큰 이유로 작용했던 것 같다. 테스트 케이스를 직접 생각해보는 시간도 필요한 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 국회의원 선거(1417번) [JS]]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EA%B5%AD%ED%9A%8C%EC%9D%98%EC%9B%90-%EC%84%A0%EA%B1%B01417%EB%B2%88-JS</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EA%B5%AD%ED%9A%8C%EC%9D%98%EC%9B%90-%EC%84%A0%EA%B1%B01417%EB%B2%88-JS</guid>
            <pubDate>Tue, 11 Feb 2025 06:30:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/6061183b-d685-49d5-902a-24974c6b681b/image.png" alt=""></p>
<h3 id="백준---국회의원-선거1417번"><a href="https://www.acmicpc.net/problem/1417">백준 - 국회의원 선거(1417번)</a></h3>
<p><img src="https://velog.velcdn.com/images/nyun-nye/post/66e518b7-9b5e-47cb-a20a-b8b95391441d/image.png" alt=""></p>
<blockquote>
<p>이 문제는 결국 반복하며 최댓값을 찾는 문제이다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li>국회의원 후보의 수를 <code>N</code>으로 받는다.</li>
<li>다솜이의 득표 수를 <code>dasom</code>으로 받고, 나머지 득표 수를 <code>vote</code> 배열로 저장한다.</li>
<li><code>counter</code> 변수를 0으로 초기화한다.</li>
<li>while 반복을하며 <code>vote</code> 배열에서의 최댓값을 구한다. 최댓값을 <code>max</code>로, 최댓값의 위치를 <code>index</code>에 저장한다.</li>
<li><code>max</code>가 <code>dasom</code>보다 크거나 같으면 최댓값에서 1을 뺀 후, <code>dasom</code>에 1을 더하고 <code>counter</code>를 증가시킨다.</li>
<li><code>max</code>가 <code>dasom</code>보다 작으면, 반복문을 빠져나와 <code>counter</code> 값을 출력한다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map(Number);

  const N = input[0];
  let dasom = input[1];
  let vote = input.slice(2, N+1);

  let counter = 0;

  while(true){
    let max = Math.max(...vote);
    let index = vote.findIndex(arg =&gt; arg === max);

    if(max &lt; dasom)
      break;
    else{
      vote[index]--;
      dasom++;
      counter++;
    }
  }

  console.log(counter);
</code></pre>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
이 문제를 스터디 시간에 간단하게 브레인스토밍을 통해 설계를 하는 과정에서 팀원 한 명이 최대히프 정렬을 사용해보는 것이 어떻냐는 말을 했었다. 직전학기 수업에서 배웠던 알고리즘을 떠올렸던 것이다. 그 말을 듣고 처음에는 최대 히프를 사용해서 해보려했으나 간단한 문제였기 때문에 코드가 더 복잡해진다는 생각이 들어 배열에서 최댓값을 구하는 방식으로 문제풀이를 했다. 그러나 최대히프 정렬이 조금 더 시간 단축엔 도움이 될 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 크게 만들기(2812번)[JS]]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%ED%81%AC%EA%B2%8C-%EB%A7%8C%EB%93%A4%EA%B8%B02812%EB%B2%88JS</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%ED%81%AC%EA%B2%8C-%EB%A7%8C%EB%93%A4%EA%B8%B02812%EB%B2%88JS</guid>
            <pubDate>Mon, 10 Feb 2025 11:55:35 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/5300e6d4-54b5-491d-843c-1bb7d4aca73b/image.png" alt=""></p>
<h3 id="백준---크게-만들기2812번"><a href="https://www.acmicpc.net/problem/2812">백준 - 크게 만들기(2812번)</a></h3>
<p><img src="https://velog.velcdn.com/images/nyun-nye/post/c5651720-a156-447d-9b2f-6e3bb247a1f9/image.png" alt=""></p>
<blockquote>
<p>정답 비율에 겁먹지 말자는 생각으로 선정하게 된 문제이다. 
다양한 방법을 시도해보았으나 스택으로 풀이하는 문제였다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li><code>N</code>으로 숫자의 길이, <code>K</code>로 지워야할 숫자의 갯수를 받는다.</li>
<li><code>numArr</code>에 숫자를 한자리씩 배열로 저장한다.</li>
<li><code>counter</code>로 지워야할 남은 갯수를 센다. 초기값은 <code>K</code>로 설정한다.</li>
<li><code>stack</code> 배열을 생성한다.</li>
<li><code>numArr</code>에 있는 <code>digit</code>의 갯수 동안 반복한다.</li>
<li>이때 <code>stack</code>의 길이가 0보다 크고, <code>stack</code>의 마지막 요소가 새로 들어올 <code>digit</code>보다 작으면서 <code>counter</code>가 0보다 크다면 <code>stack</code>에서 pop을 하며 <code>counter</code>를 감소시킨다.</li>
<li>만약 하나라도 만족하지 않는다면 <code>digit</code>값을 <code>stack</code>에 push한다.</li>
<li><span style="background-color: yellow;"><code>stack</code>에 남은 갯수가 지워져야할만큼(<code>N</code>-<code>K</code>만큼) 지워지지 않았다면, 반복하며 pop을 통해 지운다.</span></li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map((el) =&gt; el.split(&quot; &quot;));

  const N = Number(input[0][0]);
  const K = Number(input[0][1]);

  let counter = K;
  let numArr = Array.from(input[1][0]);
  let stack = [];

  for(let digit of numArr){
    while(stack.length &amp;&amp; stack[stack.length - 1] &lt; digit &amp;&amp; counter){
        stack.pop();
        counter--;
    }
    stack.push(digit);
  }

    while(stack.length &gt; N-K){
        stack.pop();
    }

  console.log(stack.join(&#39;&#39;));
</code></pre>
<hr/>

<h3 id="시행착오-1">시행착오 1</h3>
<p>처음 생각했던 방식은 처음 숫자부터 <code>K</code>번째의 숫자까지 중에서 가장 작은 값을 선택하여 삭제하는 방식을 택했다.
예를들어 입력값이</p>
<pre><code>4 2
1924</code></pre><p>로 들어온다면 [1,9,2,4] 중에서 첫번째 숫자를 제외한 제일 앞 두자리인 [1, 9, 2] 중에서 가장 작은 수인 1을 삭제한다. 아직 삭제할 횟수가 남았으므로 [9, 2, 4] 중 [9, 2] 중 가장 작은 수인 2를 삭제한다. 그러면 최종적으로 [9, 4]가 남게된다. </p>
<p>이 방식은 예제로 제시된 3가지는 통과하였으나 반례를 더 찾아본 후 옳지 않은 방법임을 알아차렸다. 이 방법의 반례는 아래와 같다.</p>
<pre><code>9 3
543211211</code></pre><p>일 경우 <code>541211</code> 가 나온다.</p>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map((el) =&gt; el.split(&quot; &quot;).map(Number));

  const N = input[0][0];
  const K = input[0][1];
  let num = String(input[1][0]);
  let numArr = Array.from(num, (el)=&gt;Number(el));

  let len = num.length;
  let end = K;

  while(len &gt; N-K){
    if(end &gt; len){
      numArr.splice(0, 1);
      len--;
      end = K;
    }
    let newNum = numArr.slice(0, end);
    let min = Math.min(...newNum);
    let max = Math.max(...newNum);
    if(min === max){
      end++;
      continue;
    }
    for(let j=0; j&lt;N; j++){
      if (newNum[j] === min){
        numArr.splice(j, 1);
        len--;
        end = K;
        break;
      }
    }
  }

  console.log(Number(numArr.join(&#39;&#39;)));</code></pre>
<h3 id="시행착오-2">시행착오 2</h3>
<p>두 번째 생각한 방식은 현재 숫자보다 큰 숫자가 뒤에 있을 경우 삭제하는 방식이다. 예를들어 입력값이</p>
<pre><code>4 2
1924</code></pre><p>라면 <code>i=0</code>일 때 <code>i</code>번째 자리는 1이다. 그럼 현재 삭제가능한 횟수가 2번이므로 1을 제외한 2자리인 [9, 2] 중 큰 수가 9이고, 9가 <code>i</code>번째 자리인 1보다 크므로 1을 삭제한다.</p>
<p>이 방법은 반례가 없었으나 메모리 초과로 인해 위에서 언급한 스택으로 문제 풀이를 하였다.</p>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map(el =&gt; el.split(&quot; &quot;));
//   .map((el) =&gt; el.split(&quot; &quot;).map(Number));

  const N = Number(input[0][0]);
  const K = Number(input[0][1]);
  const num = input[1][0];
  let numArr = Array.from(num);
  let len = numArr.length;
  let count = 0;

  for(let i = 0; i&lt;N; i++){
    if(count === K)
        break;
    tempArr = numArr.slice(i+1, i + 1 + K-count); 
    let max = Math.max(...tempArr);
    if(numArr[i] &lt; max){
        numArr.splice(i,1);
        len--;
        count++;
        i--;
    }
  }
  if(count != K){
    numArr.splice(-(K-count), (K-count));
  }

  console.log(numArr.join(&#39;&#39;));
</code></pre>
<p><span style="background-color:yellow">이때 중요했던 부분이 처음에는 아래 코드에서와 같이 배열을 숫자로 정하고 풀었는데 수의 자리수가 커지면 오버플로우로 제대로 값이 나오지 않는 경우가 발생하였다.</span> 그래서 숫자를 문자열로 두고 최종 출력에서 join을 통해 문자열을 붙여서 숫자처럼 출력했다.</p>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map((el) =&gt; el.split(&quot; &quot;).map(Number));

  const N = input[0][0];
  const K = input[0][1];
  const num = String(input[1][0]);
  let numArr = Array.from(num, (el)=&gt;Number(el)); // 숫자 배열 생성
  let len = numArr.length;
  let count = 0;

  for(let i = 0; i&lt;N; i++){
    if(count === K)
        break;
    tempArr = numArr.slice(i+1, i + 1 + K-count); 
    let max = Math.max(...tempArr);
    if(numArr[i] &lt; max){
        numArr.splice(i,1);
        len--;
        count++;
        i--;
    }
  }
  if(count != K){
    numArr.splice(-(K-count), (K-count));
  }

  console.log(Number(numArr.join(&#39;&#39;)));</code></pre>
<p>문제에서 주어지는 숫자가 최대 500,000자리까지 될 수 있는데,
입력받을 때 이미 <code>.map((el) =&gt; el.split(&quot; &quot;).map(Number))</code>를 사용해서 숫자형으로 변환하고 있다.
이 경우 15~16자리 이상의 정수는 자바스크립트의 Number(IEEE‑754 64비트 부동소수점)로 표현할 때 정밀도가 깨져서 잘못된 값이 된다.
예를 들어, 아래와 같이 20자리 이상의 숫자가 주어지는 경우,</p>
<pre><code>20 1
12345678901234567890</code></pre><p>2345678901234567890 가 되어야 한다.
그러나 이 코드가 출력하는 결과는 2345678901234567000이다.</p>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br></p>
<p>이 문제를 풀며 조금 방황했다. 위에서 보았듯이 두 가지 시행착오를 거치며 꽤 오랜 시간을 소모했다. 그러나 그 시행착오를 통해 스택을 사용해야하는 타당한 이유를 찾을 수 있었고, 스택을 사용하는 과정에서 코드를 설계하는데 보다 짧은 시간을 들일 수 있었다. 역시 실패없는 배움은 없는 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 짐 챙기는 숌(1817번)]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%A7%90-%EC%B1%99%EA%B8%B0%EB%8A%94-%EC%88%8C1817%EB%B2%88</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%A7%90-%EC%B1%99%EA%B8%B0%EB%8A%94-%EC%88%8C1817%EB%B2%88</guid>
            <pubDate>Wed, 05 Feb 2025 10:42:03 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/cd56e74a-73e2-45e1-bbff-a63d6d514edb/image.png" alt=""></p>
<h3 id="백준---짐-챙기는-숌1817번"><a href="https://www.acmicpc.net/problem/1817">백준 - 짐 챙기는 숌(1817번)</a></h3>
<h4 id="문제">문제</h4>
<ul>
<li>숌은 짐을 챙겨서 겨울캠프에서 집으로 가려고 한다. 근데 숌은 공부를 많이 하러 캠프에 온 것이기 때문에 책을 엄청나게 많이 가지고 왔다. 숌은 이 책을 방에 탑처럼 쌓아 놨다.</li>
<li>숌은 책을 박스에 차곡차곡 넣어서 택배로 미리 보내려고 한다. 책은 탑처럼 차곡차곡 쌓여있기 때문에, 차례대로 박스에 넣을 수밖에 없다.</li>
<li>각각의 책은 무게가 있다. 그리고 박스는 최대 넣을수 있는 무게가 있다. 숌이 필요한 박스의 개수의 최솟값을 구하는 프로그램을 작성하시오.</li>
</ul>
<h4 id="입력">입력</h4>
<ul>
<li>첫째 줄에 책의 개수 N과 박스에 넣을 수 있는 최대 무게 M이 주어진다. N은 0보다 크거나 같고 50보다 작거나 같은 정수이고, M은 1,000보다 작거나 같은 자연수이다. </li>
<li>N이 0보다 큰 경우 둘째 줄에 책의 무게가 공백을 사이에 두고 주어진다. 책의 무게는 M보다 작거나 같은 자연수이다.<h4 id="출력">출력</h4>
</li>
<li>첫째 줄에 필요한 박스의 개수의 최솟값을 출력한다.</li>
</ul>
<blockquote>
<p>이 문제는 다음에 올 책의 무게를 고려하는 것이 포인트이다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li>책의 갯수를 <code>N</code>으로, 최대 무게를 <code>M</code>으로 받는다.</li>
<li>각 책의 무게를 배열 <code>books</code>로 받는다.</li>
<li>박스의 갯수를 <code>counter</code>로 하여 초기값을 1로 준다.</li>
<li><code>sum</code>과 <code>nextSum</code>으로 현재 박스의 총 책의 무게의 합과 다음 책의 무게의 합을 계산한다.</li>
<li><code>N</code>만큼 루프를 돌며 현재 책의 무게가 최대무게인 <code>M</code>이랑 같아지면 <code>counter</code>를 증가하고, <code>sum</code>과 <code>nextSum</code>의 값을 초기화한다.</li>
<li>다음 책의 무게를 미리 재서 최대무게인 <code>M</code>을 초과하면 <code>counter</code>를 미리 증가하고, <code>nextSum</code>과 <code>sum</code>의 값을 초기화한다.</li>
<li>이때 책의 갯수인 <code>N</code>값이 0개이면 0을 출력한다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map((el) =&gt; el.split(&quot; &quot;).map(Number));


const N = input[0][0]; // 책의 갯수
const M = input[0][1]; // 최대 무게 M

const books = input[1];

let counter = 1;
let sum = 0;
let nextSum = 0;

for(let i=0; i&lt;N; i++){
    if(sum === M){
        counter++;
        sum = 0;
        nextSum = 0;
    }
    sum += books[i];
    nextSum = sum + books[i+1];
    if(nextSum &gt; M){
        counter++;
        nextSum = 0;
        sum = 0;
    }
}
if(N === 0)
    counter = 0;

console.log(counter);
</code></pre>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
사실 이 문제는 한 번에 풀었다. 미리 설계를 하지 않고 예제를 하나씩 넣어가면서 때려맞추기를 했다. 그래서 그런지 코드가 깔끔하지 않고 개연성이 없는 것 같다. 시간관계상 우선 이렇게 풀고 넘어간다. 더 좋은 풀이를 고민하고 추가할 계획이다. 다음부터는 좀 여유를 가지고 문제를 풀이해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 장신구 명장 임스(25496번)]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%9E%A5%EC%8B%A0%EA%B5%AC-%EB%AA%85%EC%9E%A5-%EC%9E%84%EC%8A%A425496%EB%B2%88</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%9E%A5%EC%8B%A0%EA%B5%AC-%EB%AA%85%EC%9E%A5-%EC%9E%84%EC%8A%A425496%EB%B2%88</guid>
            <pubDate>Mon, 03 Feb 2025 11:47:06 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/20c86723-e723-4a5c-992c-2c190ee124ee/image.png" alt=""></p>
<h3 id="백준---장신구-명장-임스25496번"><a href="https://www.acmicpc.net/problem/25496">백준 - 장신구 명장 임스(25496번)</a></h3>
<h4 id="문제">문제</h4>
<ul>
<li><p>메이플스토리에는 전문 기술이라는 제작 시스템이 있다. 전문 기술은 특정량의 피로도가 쌓이는 대신 다양한 장비 및 비약을 제작할 수 있는 시스템이다. 장신구 명장인 임스는 어떻게 하면 더 효율적으로 많은 장신구를 제작할 수 있을지 고민에 빠졌다.</p>
</li>
<li><p>임스가 만들 수 있는 장신구는 $N$개가 있고, 각각의 장신구를 만들면 $A_i$만큼의 피로도가 누적된다.</p>
</li>
<li><p>피로도가 $200$ 미만인 경우, 장신구를 제작할 수 있다. 현재 쌓인 피로도가 $P$일 때, 임스가 제작할 수 있는 장신구의 최대 개수를 구해보자!</p>
</li>
</ul>
<h4 id="입력">입력</h4>
<ul>
<li><p>첫 번째 줄에 정수 $P$와 정수 
$N$이 공백으로 구분되어 주어진다. 
($1 \le P \le 200$, $1 \le N \le 1,000$)</p>
</li>
<li><p>두 번째 줄에는 정수 $A_1, A_2, \dots, A_N$이 공백으로 구분되어 주어진다. ($1 \le A_i \le 200$)</p>
<h4 id="출력">출력</h4>
<p>제작할 수 있는 장신구의 최대 개수를 출력하시오.</p>
</li>
</ul>
<blockquote>
<p>이 문제는 배열 A를 오름차순 정렬하는 것이 포인트이다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li>피로도를 변수 <code>P</code>로, 장신구의 갯수를 변수 <code>N</code>으로 입력받는다.</li>
<li>각각의 장신구의 피로도를 배열 <code>A</code>로 입력받는다.</li>
<li>배열 <code>A</code>를 오름차순 정렬한다.</li>
<li><code>P</code>가 200 미만이면서 장신구의 갯수만큼 반복한다.</li>
<li>반복한 횟수를 <code>index</code>에 저장하여 출력한다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-c">#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int asc(const int* a, const int* b) {
    return *a - *b; // 오름차순
}

int main() {
    int P, N;
    scanf(&quot;%d %d&quot;, &amp;P, &amp;N);

    int A[1000];
    for (int i = 0; i &lt; N; i++) {
        scanf(&quot;%d&quot;, &amp;A[i]);
    }

    qsort(A, N, sizeof(int), asc);

    int index = 0;

    while (P&lt;200 &amp;&amp; index&lt;N) {
        P += A[index++];
    }

    printf(&quot;%d&quot;, index);
}
</code></pre>
<hr/>

<h3 id="시행착오">시행착오</h3>
<ul>
<li>C에서 오름차순, 내림차순 함수를 사용하는 것은 <a href="https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%B3%B4%EB%AC%BC1026%EB%B2%88">백준 - 보물(1026번)</a> 글에서 사용 및 설명한 적이 있다.</li>
</ul>
<h4 id="오답">오답</h4>
<pre><code class="language-c">#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int asc(const int* a, const int* b) {
    return *a - *b; // 오름차순
}

int main() {
    int P, N;
    scanf(&quot;%d %d&quot;, &amp;P, &amp;N);

    int A[1000];
    for (int i = 0; i &lt; N; i++) {
        scanf(&quot;%d&quot;, &amp;A[i]);
    }

    qsort(A, N, sizeof(int), asc);

    int index = 0;

    while (P&lt;200) { // while (P&lt;200 &amp;&amp; index&lt;N)
        P += A[index++];
    }

    printf(&quot;%d&quot;, index);
}
</code></pre>
<p>처음 시도에서는 <code>index</code>의 값이 장신구의 갯수인 <code>N</code>회를 넘어가는 것을 고려하지 못하여 틀렸었다. 이러한 반례를 찾아 수정하였다.</p>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
JS와 권태기인지 자꾸 하기 싫어져서 문제풀이를 스터디 당일까지 최대한 미루다가 푸는 중이다. 그래서 이제는 언어에 제한을 두거나 부담을 가지지 않고 우선 문제 풀이 자체에 친숙해지는 연습을 먼저 하려고 한다. 차차 연습하고 노력하다보면 분명히 성장하는 날이 올 것이다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 스터디]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%8A%A4%ED%84%B0%EB%94%94</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EC%8A%A4%ED%84%B0%EB%94%94</guid>
            <pubDate>Fri, 31 Jan 2025 05:31:44 GMT</pubDate>
            <description><![CDATA[<p>학교에서 진행하는 4박5일 동계 프로그래밍 캠프에 가게 되었다.</p>
<p>하루에 한 번씩 강연을 해주시는 졸업생 선배님들이 계셨는데 하나같이 코딩테스트를 미리 대비하는 것에 대한 중요성을 언급하셨다.</p>
<p>이를 위해 현장에서 팀원을 결성하여 스터디를 만들었다.</p>
<p>혼자서 대비하는 것보다 서로 응원해주며 새로운 문제풀이 방법을 공유할 수 있는 좋은 기회라고 생각되었기 때문이다.</p>
<p>또한 그냥 문제를 풀이하는 것보단 기록으로 남기는 것이 의미있다고 생각하여 블로그도 시작하게 되었다.</p>
<p>우리의 규칙은 아래와 같다.</p>
<blockquote>
<ol>
<li>일주일에 두 번 진행한다.</li>
<li>공통된 문제를 풀이한다. 단, 언어의 제한은 없다.
<del>나는 C, Js를 번갈아가며 진행할 계획이다.</del></li>
<li>미리 정해서 풀어온 문제에 대한 풀이 설명을 30분간 진행한다.</li>
<li>이후 30분간 현장에서 정한 문제를 다같이 풀이한다.</li>
</ol>
</blockquote>
<p>따라서 일주일에 총 4개의 공통된 문제를 풀고, 풀이를 공유할 수 있다.</p>
<p>프로그래밍 문제에 익숙해지는 과정동안은 따로 알고리즘을 공부하며 풀지 않고 기본적인 문제풀이만 진행한다. 익숙해지는 여름방학부터 알고리즘을 공부하며 관련 문제를 풀어나갈 계획이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 동전 0(11047번)]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%8F%99%EC%A0%84-011047%EB%B2%88</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%8F%99%EC%A0%84-011047%EB%B2%88</guid>
            <pubDate>Fri, 31 Jan 2025 05:21:17 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/8d1d08c2-fa70-4da7-962d-0b70f185498c/image.png" alt=""></p>
<h3 id="백준---동전-011047번"><a href="https://www.acmicpc.net/problem/11047">백준 - 동전 0(11047번)</a></h3>
<h4 id="문제">문제</h4>
<ul>
<li>준규가 가지고 있는 동전은 총 N종류이고, 각각의 동전을 매우 많이 가지고 있다.</li>
<li>동전을 적절히 사용해서 그 가치의 합을 K로 만들려고 한다. 이때 필요한 동전 개수의 최솟값을 구하는 프로그램을 작성하시오.</li>
</ul>
<h4 id="입력">입력</h4>
<ul>
<li>첫째 줄에 N과 K가 주어진다. (1 ≤ N ≤ 10, 1 ≤ K ≤ 100,000,000) 둘째 줄부터 N개의 줄에 동전의 가치 Ai가 오름차순으로 주어진다. (1 ≤ Ai ≤ 1,000,000, A1 = 1, i ≥ 2인 경우에 Ai는 Ai-1의 배수)<h4 id="출력">출력</h4>
</li>
<li>첫째 줄에 K원을 만드는데 필요한 동전 개수의 최솟값을 출력한다.</li>
</ul>
<blockquote>
<p>동전이 오름차순으로 주어지기 때문에 따로 재배열할 필요가 없다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li>동전의 가짓수를 <code>N</code>으로 입력받는다.</li>
<li>금액을 <code>K</code>로 입력받는다.</li>
<li><code>N</code>만큼 반복하며 <code>K</code>를 각 금액으로 나눈 값을 합하고, <code>K</code>에 나머지를 저장하여 다시 반복한다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map((el) =&gt; el.split(&quot; &quot;).map(Number));


  const N = input[0][0];
  let K = input[0][1];

  let num = 0;
  for(let i=N; i&gt;0; i--){
    if(K === 0)
        break;
    if(K &gt;= input[i][0]){
        num += Math.floor(K/input[i][0]);
        K %= input[i][0];
    }
  }

  console.log(num);
</code></pre>
<hr/>

<h3 id="js로-백준-풀기">Js로 백준 풀기</h3>
<p><a href="https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%B3%B4%EB%AC%BC1026%EB%B2%88">이전 문제 풀이</a>에서 언급했듯이 Js로 백준을 푸는 것은 꽤나 까다롭다. 그래서 계속 피해왔지만 그래도 풀어야한다. <a href="https://minjo0n.tistory.com/2">이 글</a>을 참고해서 문제를 풀었다. 혹시 Js로 문제풀이를 할 경우 참고하시길 바란다.</p>
<p>간략하게 설명하자면</p>
<pre><code class="language-js">const input = require(&quot;fs&quot;)
  .readFileSync(process.platform === &quot;linux&quot; ? &quot;/dev/stdin&quot; : &quot;./input.txt&quot;)
  .toString()
  .trim()
  .split(&quot;\n&quot;)
  .map((el) =&gt; el.split(&quot; &quot;).map(Number));</code></pre>
<p>백준은 리눅스 환경에서 실행된다. VSCode에서 실행을 위해 삼항연산자를 활용하여 input.txt 파일을 동일 디렉토리에 저장해 사용한다.</p>
<p><code>.toString()</code>을 사용하여 입력값을 문자열로 받고, <code>.trim()</code>으로 공백을 제거한 후, <code>.split(&quot;\n&quot;)</code>으로 줄바꿈을 기준으로 문자열을 나눈다. <code>.map()</code>은 새로운 배열을 반환해주는 함수이다.</p>
<p>예를들어 해당 문제에서 입력이 아래와 같은 형식으로 들어온다.</p>
<pre><code>10 4200
1
5
10
50
100
500
1000
5000
10000
50000</code></pre><ol>
<li><code>.toString()</code>으로 해당 입력값들을 문자열로 변환한다.</li>
<li><code>.trim()</code>으로 혹시 모를 공백을 제거한다.</li>
<li><code>.split(&quot;\n&quot;)</code>으로 배열을 생성한다. <pre><code> [
   &quot;10 4200&quot;,
   &quot;1&quot;,
   &quot;5&quot;,
   &quot;10&quot;,
   &quot;50&quot;,
   &quot;100&quot;,
   &quot;500&quot;,
   &quot;1000&quot;,
   &quot;5000&quot;,
   &quot;10000&quot;,
   &quot;50000&quot;
 ]</code></pre></li>
<li><code>.map()</code>으로 각 문자열을 공백을 기준으로 분리하고 숫자로 변환한다. <pre><code>[
 [10, 4200],
 [1],
 [5],
 [10],
 [50],
 [100],
 [500],
 [1000],
 [5000],
 [10000],
 [50000]
]</code></pre></li>
</ol>
<p>기본적인 틀은 위와 같고 입력받는 값에 따라 잘 변환해서 사용하면 된다.</p>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
역시 백준을 Js로 풀 때는 입력받는 것에 신경을 잘 써야하는 것이 번거롭고 어렵다. 이 부분으로 인해 두 번이나 오답이 발생했다. 더 익숙해지도록 노력해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 보물(1026번)]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%B3%B4%EB%AC%BC1026%EB%B2%88</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%B3%B4%EB%AC%BC1026%EB%B2%88</guid>
            <pubDate>Mon, 27 Jan 2025 17:25:06 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/3038c3c4-efb8-4179-aa10-fb89a9e3013d/image.png" alt=""></p>
<h3 id="백준---보물1026번"><a href="https://www.acmicpc.net/problem/1026">백준 - 보물(1026번)</a></h3>
<h4 id="문제">문제</h4>
<ul>
<li>옛날 옛적에 수학이 항상 큰 골칫거리였던 나라가 있었다. 이 나라의 국왕 김지민은 다음과 같은 문제를 내고 큰 상금을 걸었다.</li>
</ul>
<ul>
<li><p>길이가 N인 정수 배열 A와 B가 있다. 다음과 같이 함수 S를 정의하자.
S = A[0] × B[0] + ... + A[N-1] × B[N-1]
S의 값을 가장 작게 만들기 위해 A의 수를 재배열하자. 단, B에 있는 수는 재배열하면 안 된다.</p>
</li>
<li><p>S의 최솟값을 출력하는 프로그램을 작성하시오.</p>
</li>
</ul>
<h4 id="입력">입력</h4>
<ul>
<li>첫째 줄에 N이 주어진다. 둘째 줄에는 A에 있는 N개의 수가 순서대로 주어지고, 셋째 줄에는 B에 있는 수가 순서대로 주어진다. N은 50보다 작거나 같은 자연수이고, A와 B의 각 원소는 100보다 작거나 같은 음이 아닌 정수이다.<h4 id="출력">출력</h4>
</li>
<li>첫째 줄에 S의 최솟값을 출력한다.</li>
</ul>
<blockquote>
<p>이 문제에서 포인트는 하나의 배열을 오름차순, 다른 하나의 배열을 내림차순으로 정리한 후 각 인덱스의 배열끼리 곱해서 합하는 것이다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li>수의 갯수를 <code>N</code>으로 입력받는다.</li>
<li><code>A</code> 배열과 <code>B</code> 배열의 값을 입력받는다.</li>
<li><code>A</code> 배열을 오름차순으로, <code>B</code> 배열을 내림차순으로 정렬한다.</li>
<li>각 인덱스의 값끼리 곱하여 합한다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int asc(const int* a, const int* b) {
    return *a - *b; // 오름차순
}

int dsc(const int* a, const int* b) {
    return *b - *a; // 내림차순
}

int main() {
    int N;
    int A[50];
    int B[50];
    int S = 0;

    scanf(&quot;%d&quot;, &amp;N);
    for (int i = 0; i &lt; N; i++) {
        scanf(&quot;%d&quot;, &amp;A[i]);
    }
    for (int i = 0; i &lt; N; i++) {
        scanf(&quot;%d&quot;, &amp;B[i]);
    }

    qsort(A, N, sizeof(int), asc);
    qsort(B, N, sizeof(int), dsc);

    for (int i = 0; i &lt; N; i++) {
        S += (A[i] * B[i]);
    }

    printf(&quot;%d&quot;, S);
}
</code></pre><hr/>

<h3 id="qsort-함수">qsort() 함수</h3>
<p>이번 코드에서는 정렬함수를 사용해서 문제를 해결했다.</p>
<p>우선 <code>qsort()</code> 함수를 사용하기 위해서는 <code>&lt;stdlib.h&gt;</code>를 import 해와야한다.
첫 번째 인자로는 정렬할 배열의 <strong>시작 주소</strong>를 넘겨준다. 두 번째 인자로는 요소의 갯수를 넘겨준다. 세 번째 인자로는 요소의 크기를 넘겨준다. <span style="background-color: yellow">마지막 인자에는 정렬 기준을 세우는 함수를 넘겨주어야한다.</span></p>
<p>정렬 기준 함수라는 것은 쉽게 말하면 <strong>반환값이 양수이면 두 수의 자리를 바꾸고 음수이면 자리를 바꾸지 않는다.</strong> 문제 해결에서 사용한 코드를 예시로 설명하겠다.</p>
<pre><code>    int asc(const int* a, const int* b) {
        return *a - *b; // 오름차순
    }</code></pre><p><span style="background-color: yellow">오름차순</span>의 경우 a-b의 값이 <strong>양수(a&gt;b)</strong>이면 두 수의 <strong>자리를 바꾼다.</strong> a는 b보다 큰 수 이면서 먼저 오는 수이므로 이 수가 뒤로가게된다. 반대로 a-b의 값이 <strong>음수(a&lt;b)</strong>이면 두 수의 <strong>자리를 바꾸지 않는다.</strong> 이때는 작은 수가 앞에 있도록 고정된다. 이 과정을 반복하면서 큰수가 뒤로가게 되므로 자연스럽게 오름차순 정렬이 된다. </p>
<pre><code>    int dsc(const int* a, const int* b) {
        return *b - *a; // 내림차순
    }</code></pre><p><span style="background-color: yellow">내림차순</span>의 경우 오름차순과 반대로 생각하여 뒷 순서인 b-a의 값을 구하는 코드로 수정하면 된다.</p>
<hr/>

<p><span style="font-weight: 600;">💡한줄평</span></br>
C언어로 문제를 푸는 것은 백준에서 JS로 문제를 푸는 것이 복잡하거니와 순전히 시간복잡도를 고려하지 않고 싶어서였다.
그러나 이 문제를 풀면서 정렬함수의 오름차순, 내림차순을 구현하기 위해 기준이 되는 함수를 만들어야되는 것에 피로감을 느꼈다. 또한, 프론트엔드 개발자를 희망하는 사람으로서 JS를 놓을 수는 없다. 다음 문제는 JS로 풀이해야겠다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - ATM(11399번)]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-ATM11399%EB%B2%88</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-ATM11399%EB%B2%88</guid>
            <pubDate>Sun, 26 Jan 2025 16:36:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/nyun-nye/post/f7a8fc82-3ce4-4293-be79-f3d0aa302d82/image.png" alt=""></p>
<h3 id="백준---단어-공부11399번"><a href="https://www.acmicpc.net/problem/11399">백준 - 단어 공부(11399번)</a></h3>
<h4 id="문제">문제</h4>
<ul>
<li>인하은행에는 ATM이 1대밖에 없다. 지금 이 ATM앞에 N명의 사람들이 줄을 서있다. 사람은 1번부터 N번까지 번호가 매겨져 있으며, i번 사람이 돈을 인출하는데 걸리는 시간은 Pi분이다.<ul>
<li>사람들이 줄을 서는 순서에 따라서, 돈을 인출하는데 필요한 시간의 합이 달라지게 된다. 예를 들어, 총 5명이 있고, P1 = 3, P2 = 1, P3 = 4, P4 = 3, P5 = 2 인 경우를 생각해보자. [1, 2, 3, 4, 5] 순서로 줄을 선다면, 1번 사람은 3분만에 돈을 뽑을 수 있다. 2번 사람은 1번 사람이 돈을 뽑을 때 까지 기다려야 하기 때문에, 3+1 = 4분이 걸리게 된다. 3번 사람은 1번, 2번 사람이 돈을 뽑을 때까지 기다려야 하기 때문에, 총 3+1+4 = 8분이 필요하게 된다. 4번 사람은 3+1+4+3 = 11분, 5번 사람은 3+1+4+3+2 = 13분이 걸리게 된다. 이 경우에 각 사람이 돈을 인출하는데 필요한 시간의 합은 3+4+8+11+13 = 39분이 된다.</li>
<li>줄을 [2, 5, 1, 4, 3] 순서로 줄을 서면, 2번 사람은 1분만에, 5번 사람은 1+2 = 3분, 1번 사람은 1+2+3 = 6분, 4번 사람은 1+2+3+3 = 9분, 3번 사람은 1+2+3+3+4 = 13분이 걸리게 된다. 각 사람이 돈을 인출하는데 필요한 시간의 합은 1+3+6+9+13 = 32분이다. 이 방법보다 더 필요한 시간의 합을 최소로 만들 수는 없다.</li>
</ul>
</li>
</ul>
<ul>
<li>줄을 서 있는 사람의 수 N과 각 사람이 돈을 인출하는데 걸리는 시간 Pi가 주어졌을 때, 각 사람이 돈을 인출하는데 필요한 시간의 합의 최솟값을 구하는 프로그램을 작성하시오.</li>
</ul>
<h4 id="입력">입력</h4>
<ul>
<li>첫째 줄에 사람의 수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄에는 각 사람이 돈을 인출하는데 걸리는 시간 Pi가 주어진다. (1 ≤ Pi ≤ 1,000)<h4 id="출력">출력</h4>
</li>
<li>첫째 줄에 각 사람이 돈을 인출하는데 필요한 시간의 합의 최솟값을 출력한다.</li>
</ul>
<blockquote>
<p>이 문제에서 포인트는 오름차순으로 값을 누적해서 더하는 것이다.</p>
</blockquote>
<hr />

<h3 id="코드-설계">코드 설계</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li>사람의 수를 <code>N</code>으로 입력받는다. 이때 사람의 수는 1000이하이다. </li>
<li>각 사람의 시간을 배열 <code>P</code>에 저장한다. 그와 동시에 <code>check</code>라는 배열을 0으로 초기화한다. 이 배열의 용도는 선택 여부이다.</li>
<li><code>check</code>가 0인 사람의 시간 중 최솟값 <code>min</code>을 구한다. 이때 <code>min</code>은 반복문 내에서 시간의 최댓값인 1000으로 초기화한다.</li>
<li>사람 수만큼 반복문을 돌면서 누적 값을 <code>sum</code>으로 설정하고 총 합계를 <code>total</code>로 설정하여 최종적으로 <code>total</code>을 출력한다.</li>
</ol>
<hr />

<h3 id="제출한-답">제출한 답</h3>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdio.h&gt;

int main() {
    int N;
    int P[1000];
    int check[1000];
    int sum = 0;
    int total = 0;
    int count = 0;
    int index = 0;

    // 사람 수 받기
    scanf(&quot;%d&quot;, &amp;N);

    // 각 사람에 따른 시간 받기 + check 배열 초기화
    for (int i = 0; i &lt; N; i++) {
        scanf(&quot;%d&quot;, &amp;P[i]);
        check[i] = 0;
    }

    while (count &lt; N) {
        ++count;
        int min = 1000;
        for (int i = 0; i &lt; N; i++) {
            if ((min &gt; P[i]) &amp;&amp; (check[i] == 0)) {
                min = P[i];
                index = i;
            }
        }
        check[index] = 1;
        sum += min;        
        total += sum;
    }

    printf(&quot;%d&quot;, total);
}
</code></pre><hr/>

<p>  <span style="font-weight: 600;">💡한줄평</span></br>
이 문제를 푸는데 다른 문제에 비해 많은 시간을 들이지 않았다. C 사용에 익숙해진 것인지 이 문제가 쉬웠던 것인지는 아직 판단이 되지 않는다. C언어는 시간이 짧게 걸리는 것이 장점인 것 같다. 그러나 추후 오름차순 정렬하는 알고리즘을 학습한 후 빅오 계산법을 활용해서 비교해보고 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 단어 공부(1157번)]]></title>
            <link>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%8B%A8%EC%96%B4-%EA%B3%B5%EB%B6%801157%EB%B2%88</link>
            <guid>https://velog.io/@nyun-nye/%EB%B0%B1%EC%A4%80-%EB%8B%A8%EC%96%B4-%EA%B3%B5%EB%B6%801157%EB%B2%88</guid>
            <pubDate>Wed, 22 Jan 2025 06:27:57 GMT</pubDate>
            <description><![CDATA[<h3 id="백준---단어-공부1157번"><a href="https://www.acmicpc.net/problem/1157">백준 - 단어 공부(1157번)</a></h3>
<div style="border: 3px solid #B3EBD8; padding: 4px; border-radius: 20px;">

<h4 id="문제">문제</h4>
<ul>
<li>알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.<h4 id="입력">입력</h4>
</li>
<li>첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.<h4 id="출력">출력</h4>
</li>
<li>첫째 줄에 이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.</div>


</li>
</ul>
<blockquote>
<p>오랜만에 C언어로 문제를 풀어서 그런지 언어 사용하는 것에 익숙해지는데 시간이 꽤 오래 걸렸다. 아래는 문제를 해결하는 과정에서 어려움을 겪었던 문법들이다.</p>
</blockquote>
<h3 id="시행-착오">시행 착오</h3>
<p>문제 해결의 단계는 아래와 같다.</p>
<ol>
<li>단어를 입력받아야한다. C에서는 문자열 자체를 입력받기가 어려워 배열로 문자열을 받으려 시도했다. 이때 가변배열을 사용하려했으나 주의할 점은 입력받을 때 문자열의 길이가 정해지지 않는다는 것이다. 이를 해결하고자 <code>realloc()</code>으로 재할당을 시도했다.</li>
<li>입력받은 단어를 대문자로 변환한다. 이 과정에서 <code>toupper();</code> 함수를 사용한다. <code>&lt;ctype.h&gt;</code>를 include 해야한다.</li>
<li>대문자로 변환한 알파벳에서 각각 입력받은 횟수를 배열에 저장한다.</li>
<li>각 알파벳 중 가장 많이 사용된 알파벳의 갯수를 알아낸다. 이를 max 변수에 저장한다.</li>
<li>가장 많이 사용된 알파벳이 여러 개 존재하는 경우를 판별하기 위해 max 값만큼의 값을 가진 알파벳이 2개 이상이면 &quot;?&quot;를 출력한다.</li>
</ol>
<h4 id="1차-시도">1차 시도</h4>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;ctype.h&gt;
  int main() {
      int size = 10;
      int count = 0;
      char string[26] = { 0 }; // 알파벳 26개를 카운트하기 위한 배열
      char* word = (char*)malloc(size * sizeof(char));
      int max = 0;
      int index = 0;
      int check = 0;

      for (int i = 0;; i++) {
          if (count == size) {
              size *= 2;
              word = realloc(word, size * sizeof(char));
          }

          scanf(&quot;%c&quot;, &amp;word[i]);
          count++;
          if (word[i] == &#39;\n&#39;) {
              word[i] = &#39;\0&#39;; // 문자열의 끝을 표시
              break;
          }
      }

      for (int i = 0; i &lt; count; i++) {
          word[i] = toupper(word[i]);
          if (word[i] &gt;= &#39;A&#39; &amp;&amp; word[i] &lt;= &#39;Z&#39;) {
              string[word[i] - &#39;A&#39;]++;
          }
      }

      for (int i = 0; i &lt; 26; i++) {
          if (string[i] &gt; 0 &amp;&amp; string[i] &gt; max) {
              max = string[i];
              index = i;
          }
      }

      for (int i = 0; i &lt; 26; i++) {
          if (string[i] &gt; 0 &amp;&amp; string[i] == max) {
              check++;
          }
          if (check &gt;= 2) {
              printf(&quot;?&quot;);
              return;
          }
      }

      printf(&quot;%c&quot;, index + &#39;A&#39;);

      free(word); // 동적 메모리 해제
      return 0;
  }</code></pre><blockquote>
<p>이 부분에서 문제가 된 점은 <code>string</code> 배열을 <code>char</code> 타입으로 설정한 것이다. <code>string</code> 배열은 각 알파벳의 갯수를 카운트하기 위한 배열이므로 <code>int</code> 타입으로 수정하고 난 후 해결되었다.</p>
</blockquote>
<h4 id="2차-시도">2차 시도</h4>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;ctype.h&gt; // 이게 머지?
int main() { // 런타임 에러
      int size = 10;
      int count = 0;
      int string[26] = { 0 }; // 알파벳 26개를 카운트하기 위한 배열
      char* word = (char*)malloc(size * sizeof(char));
      int max = 0;
      int index = 0;
      int check = 0;

      for (int i = 0;; i++) {
          if (count == size) {
              size *= 2;
              word = realloc(word, size * sizeof(char));
          }

          scanf(&quot;%c&quot;, &amp;word[i]);
          count++;
          if (word[i] == &#39;\n&#39;) {
              word[i] = &#39;\0&#39;; // 문자열의 끝을 표시
              break;
          }
      }

      for (int i = 0; i &lt; count; i++) {
          word[i] = toupper(word[i]);
          if (word[i] &gt;= &#39;A&#39; &amp;&amp; word[i] &lt;= &#39;Z&#39;) {
              string[word[i] - &#39;A&#39;]++;
          }
      }

      for (int i = 0; i &lt; 26; i++) {
          if (string[i] &gt; 0 &amp;&amp; string[i] &gt; max) {
              max = string[i];
              index = i;
          }
      }

      for (int i = 0; i &lt; 26; i++) {
          if (string[i] &gt; 0 &amp;&amp; string[i] == max) {
              check++;
          }
          if (check &gt;= 2) {
              printf(&quot;?&quot;);
              return;
          }
      }

      printf(&quot;%c&quot;, index + &#39;A&#39;);

      free(word); // 동적 메모리 해제
      return 0;
  }</code></pre><blockquote>
<p><code>string</code> 배열의 타입을 <code>int</code>로 수정하고 난 후에는 런타임 에러가 발생하였다. 여러 문제점을 찾아보았다.</p>
</blockquote>
<h4 id="span-stylecolor-red내가-생각한-문제점span"><span style="color: red;">내가 생각한 문제점</span></h4>
<ol>
<li>배열의 동적 할당
 배열을 동적으로 할당받지 않고 처리하면 이 문제를 해결할 수 있을지도 모른다. 또한, 굳이 이 문제에서 배열을 동적으로 처리할 필요성이 없다고 느껴진다. 문제를 다시 읽어보니 문제 내에서 단어의 길이가 정해져 있기 때문이다.</li>
<li><code>\n</code>문제
 문자열의 끝을 표시할 때 <code>\n</code>을 사용할 이유가 없다. 단어는 공백이 없고, <code>scanf</code> 함수는 공백이 입력되면 자동으로 입력이 끝났다고 처리하기 때문이다.</li>
<li>전반적인 코드의 복잡성
 코드가 전체적으로 복잡하게 짜여있다고 생각되었다. 코드를 조금 더 간결하게 구성하여 문제점이 한 눈에 보이게 할 필요가 있다.</li>
</ol>
<p>이러한 문제점들을 개선하여 제출한 답은 아래와 같다.</p>
<h3 id="제출한-답">제출한 답</h3>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdio.h&gt;
#include &lt;ctype.h&gt; // toupper 사용 위함
#include &lt;string.h&gt; // strlen 사용 위함


int main() {
    char word[1000000];
    scanf(&quot;%s&quot;, word);
    int len = strlen(word);
    int string[26] = {0}; // 26개 알파벳
    int max=0;
    int count = 0;
    int index;

    for (int i = 0; i &lt; len; i++) {
        word[i] = toupper(word[i]);
        string[word[i] - &#39;A&#39;]++;
    }
    for (int i = 0; i &lt; 26; i++) {
        if (string[i] &gt; 0 &amp;&amp; max &lt; string[i]) {
            max = string[i];
            index = i;
        }
    }
    for (int i = 0; i &lt; 26; i++) {
        if (max == string[i])
            count++;
    }
    if (count &gt; 1) {
        printf(&quot;?&quot;);
    }
    else {
        printf(&quot;%c&quot;, &#39;A&#39; + index);
    }
}</code></pre><div style="background-color: #B3EBD8; color: white; border-radius: 20px; padding: 40px;">
  <span style="font-weight: 600;">💡한줄평</span></br>
C언어를 2023년 1학기에 학습하고 그 이후로 오랜만에 C언어로 문제풀이를 진행했다. 그래서 그런지 C문법에 익숙해지는데 시간이 조금 걸릴 것 같다. 앞으로 C로 문제 많이 풀어봐야징~
</div>]]></description>
        </item>
    </channel>
</rss>