<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>kimbyeongnyeon 님의 블로그</title>
    <link>https://kimbyeongnyeon.tistory.com/</link>
    <description>kimbyeongnyeon 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Wed, 15 Jul 2026 10:03:13 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>kimbyeongnyeon</managingEditor>
    <item>
      <title>ATM</title>
      <link>https://kimbyeongnyeon.tistory.com/66</link>
      <description>&lt;h1&gt;ATM&lt;/h1&gt;
&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;인하은행에는 ATM이 1대밖에 없다. 지금 이 ATM앞에 N명의 사람들이 줄을 서있다. 사람은 1번부터 N번까지 번호가 매겨져 있으며, i번 사람이 돈을 인출하는데 걸리는 시간은 P&lt;/p&gt;
&lt;p&gt;i&lt;/p&gt;
&lt;p&gt;분이다.&lt;/p&gt;
&lt;p&gt;사람들이 줄을 서는 순서에 따라서, 돈을 인출하는데 필요한 시간의 합이 달라지게 된다. 예를 들어, 총 5명이 있고,&lt;br&gt;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분이 된다.&lt;/p&gt;
&lt;p&gt;줄을 [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분이다. 이 방법보다 더 필요한 시간의 합을 최소로 만들 수는 없다.&lt;/p&gt;
&lt;p&gt;줄을 서 있는 사람의 수 N과 각 사람이 돈을 인출하는데 걸리는 시간 P&lt;/p&gt;
&lt;p&gt;i&lt;/p&gt;
&lt;p&gt;가 주어졌을 때, 각 사람이 돈을 인출하는데 필요한 시간의 합의 최솟값을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h2&gt;예제 입력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;5
3 1 4 3 2&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;예제 출력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;32&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const fs = require(&amp;quot;fs&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const input = fs
  .readFileSync(process.platform === &amp;quot;linux&amp;quot; ? &amp;quot;dev/stdin&amp;quot; : &amp;quot;input.txt&amp;quot;)
  .toString()
  .trim()
  .split(&amp;quot;\n&amp;quot;);

const solution = (input) =&amp;gt; {
  const N = Number(input[0]);
  const arr = input[1]
    .split(&amp;quot; &amp;quot;)
    .map(Number)
    .sort((a, b) =&amp;gt; a - b);

  // 누적합
  let preSum = 0;
  // 결과
  let answer = 0;
  for (let i = 0; i &amp;lt; N; i++) {
    // 누적합 갱신
    preSum += arr[i];
    // 결과값에 누적합 합산
    answer += preSum;
  }
  console.log(answer);
};
solution(input);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;아이디어 / 접근법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;배열 오름차순으로 정렬&lt;/li&gt;
&lt;li&gt;순회해서 누적합에 합산&lt;/li&gt;
&lt;li&gt;결과에 누적합 합산&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;후기&lt;/h3&gt;
&lt;p&gt;오름차순 정렬 후 누적합 합산과 결과 누적만 하면 되는 문제&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>그리디</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/66</guid>
      <comments>https://kimbyeongnyeon.tistory.com/66#entry66comment</comments>
      <pubDate>Sun, 1 Feb 2026 16:47:58 +0900</pubDate>
    </item>
    <item>
      <title>회의실 배정</title>
      <link>https://kimbyeongnyeon.tistory.com/65</link>
      <description>&lt;h1&gt;회의실 배정&lt;/h1&gt;
&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;한 개의 회의실이 있는데 이를 사용하고자 하는 N개의 회의에 대하여 회의실 사용표를 만들려고 한다. 각 회의 I에 대해 시작시간과 끝나는 시간이 주어져 있고, 각 회의가 겹치지 않게 하면서 회의실을 사용할 수 있는 회의의 최대 개수를 찾아보자. 단, 회의는 한번 시작하면 중간에 중단될 수 없으며 한 회의가 끝나는 것과 동시에 다음 회의가 시작될 수 있다. 회의의 시작시간과 끝나는 시간이 같을 수도 있다. 이 경우에는 시작하자마자 끝나는 것으로 생각하면 된다.&lt;/p&gt;
&lt;h2&gt;예제 입력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;11
1 4
3 5
0 6
5 7
3 8
5 9
6 10
8 11
8 12
2 13
12 14&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;예제 출력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;4&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const fs = require(&amp;quot;fs&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const input = fs
  .readFileSync(process.platform === &amp;quot;linux&amp;quot; ? &amp;quot;/dev/stdin&amp;quot; : &amp;quot;input.txt&amp;quot;)
  .toString()
  .trim()
  .split(&amp;quot;\n&amp;quot;);

const solution = (input) =&amp;gt; {
  const N = Number(input.shift());
  const rooms = input.map((line) =&amp;gt; line.split(&amp;quot; &amp;quot;).map(Number));

  // start 기준 정렬
  rooms.sort((a, b) =&amp;gt; {
    if (a[1] === b[1]) return a[0] - b[0]; // end 같으면 start 오름차순
    return a[1] - b[1]; // end 오름차순
  });

  let cnt = 0;
  // 가장 최소값
  let lastEnd = -Infinity;

  for (const [start, end] of rooms) {
    // 현재 시작할 수 있는 회의실의 시간과 그 전에 끝난 회의실의 시간과 같다면
    if (lastEnd &amp;lt;= start) {
      // 카운팅
      cnt++;
      // 끝난 회의실 재할당
      lastEnd = end;
    }
  }

  console.log(cnt);
};

solution(input);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;아이디어 / 접근법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;우선 끝나는 시간으로 정렬 만약, 끝나는 시간이 같다면 시작시간으로 정렬&lt;/li&gt;
&lt;li&gt;끝나는 시간 기준으로 다음 회의실 찾기&lt;/li&gt;
&lt;li&gt;이전에 끝난 회의실의 시간이 현재 시작하는 시간보다 작다면 회의실을 대여할 수 있으므로 회의실을 빌리고 현재 회의실의 끝나는 시간을 재할당&lt;/li&gt;
&lt;li&gt;cnt 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;후기&lt;/h3&gt;
&lt;p&gt;그리디 중에서 가장 유명한 회의실 문제 였고 끝나는 시간으로 정렬을 할 수 있다면 크게 어려운 문제는 아니었다고 생각함. 끝나는 시간과 다음 회의실의 시작 시간을 비교해서 카운팅 해주고 끝나는 시간 바꿔주면 되는 문제&lt;/p&gt;</description>
      <category>그리디</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/65</guid>
      <comments>https://kimbyeongnyeon.tistory.com/65#entry65comment</comments>
      <pubDate>Sun, 1 Feb 2026 16:44:16 +0900</pubDate>
    </item>
    <item>
      <title>삼삼한 수</title>
      <link>https://kimbyeongnyeon.tistory.com/64</link>
      <description>&lt;h1&gt;삼삼한 수&lt;/h1&gt;
&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;준하는 3의 거듭제곱인 수만 사용하여 만들 수 있는 수를 보면 삼삼한 느낌을 받는다.&lt;/p&gt;
&lt;p&gt;이 느낌을 정확히 설명하자면, 3의 거듭제곱인 수들을 겹치지 않고 한번씩만 더해서 어떤 수 x를 만들 수 있다면 그 수는 삼삼하다고 한다. 삼삼한 수는 3의 거듭제곱인 수가 반드시 하나 이상 포함되어야 한다.&lt;/p&gt;
&lt;p&gt;예를 들어, 109는 3&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;+3&lt;/p&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;p&gt;+3&lt;/p&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;p&gt;로 나타낼 수 있으므로 삼삼한 수이다. 하지만 7과 18은 삼삼하지 않다.&lt;/p&gt;
&lt;p&gt;준하는 삼삼한 수가 얼마나 더 있는 지 알아보려고 한다.&lt;/p&gt;
&lt;h2&gt;예제 입력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;109&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;예제 출력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;YES&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const fs = require(&amp;quot;fs&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const input = fs
  .readFileSync(process.platform === &amp;quot;linux&amp;quot; ? &amp;quot;dev/stdin&amp;quot; : &amp;quot;input.txt&amp;quot;)
  .toString()
  .trim()
  .split(&amp;quot;\n&amp;quot;);

const solution = (input) =&amp;gt; {
  let n = Number(input[0]);
  // 0 이 입력으로 들어오면 리턴
  if (n === 0) {
    console.log(&amp;quot;NO&amp;quot;);
    return;
  }
  while (0 &amp;lt; n) {
    /**
     * n 에서 3을 나눈 값이 2 일 때가 의미하는 것은
     * 3진수의 관점에서 봤을 때 2가 나오면 해당 자리의 수를
     * 2번 썼다는 의미이기 때문에 규칙에 위배됨 따라서 2가 나오면
     * NO 출력 후 return
     * 예를 들어서 n 이 18일 때
     * case 1 : n / 3 = 6 n % 3 = 0
     * case 2 : n / 3 = 2 n % 3 = 0
     * case 3 : n / 3 = 0.66... n % 3 = 2
     * 이런 식으로 나오게 되는데 이를 3진수로 표현하면 200 이 된다 
     * 이 200의 의미는 3 ** 2 를 2번 썼다는 의미 이므로 9 + 9 
     * 해당 문제의 규칙에 위배 되게 된다.
     */
    if (n % 3 === 2) {
      console.log(&amp;quot;NO&amp;quot;);
      return;
    }
    n = Math.floor(n / 3);
  }
  console.log(&amp;quot;YES&amp;quot;);
};

solution(input);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;아이디어 / 접근법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;n이 0 이라면 바로 출력&lt;/li&gt;
&lt;li&gt;n 을 계속 나눠주며 나머지가 2라면 NO 출력&lt;/li&gt;
&lt;li&gt;아니라면 계속 나눠줌&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;후기&lt;/h3&gt;
&lt;p&gt;처음에는 그냥 n에서 가장 가까운 3의 제곱수를 찾은 다음 그 수에서 3씩 나눠가면서 구해주다가 마지막에 1, 3, 9 가 나오면 YES 아니면 NO 를 출력해주도록 했음 근데 시간초과가 나게 되었음. 그래서 생각을 해보다가 해당 숫자를 3진수의 관점에서 보면 2가 나머지로 나올 때 해당 자리의 숫자를 2번 썼다는 걸 파악하게 되었고 그렇게 풀다보니 성공했음&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>사칙연산</category>
      <category>수학</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/64</guid>
      <comments>https://kimbyeongnyeon.tistory.com/64#entry64comment</comments>
      <pubDate>Sun, 1 Feb 2026 16:42:57 +0900</pubDate>
    </item>
    <item>
      <title>리코쳇 로봇</title>
      <link>https://kimbyeongnyeon.tistory.com/63</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 설명&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리코쳇 로봇이라는 보드게임이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 보드게임은 격자모양 게임판 위에서 말을 움직이는 게임으로, 시작 위치에서 출발한 뒤 목표 위치에 정확하게 멈추기 위해 최소 몇 번의 이동이 필요한지 말하는 게임입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 게임에서 말의 이동은 현재 위치에서 상, 하, 좌, 우 중 한 방향으로 게임판 위의 장애물이나 게임판 가장자리까지 부딪힐 때까지 미끄러져 움직이는 것을 한 번의 이동으로 정의합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 보드게임판을 나타낸 예시입니다. (&quot;.&quot;은 빈 공간을, &quot;R&quot;은 로봇의 처음 위치를, &quot;D&quot;는 장애물의 위치를, &quot;G&quot;는 목표지점을 나타냅니다.)&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;...D..R
.D.G...
....D.D
D....D.
..D....&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 최소 움직임은 7번이며 &quot;R&quot; 위치에서 아래, 왼쪽, 위, 왼쪽, 아래, 오른쪽, 위 순서로 움직이면 &quot;G&quot; 위치에 멈춰 설 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;265&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBDXyi/dJMcaaD9dGu/GTiQk3kSXrnWWTedNZGkY1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBDXyi/dJMcaaD9dGu/GTiQk3kSXrnWWTedNZGkY1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBDXyi/dJMcaaD9dGu/GTiQk3kSXrnWWTedNZGkY1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBDXyi%2FdJMcaaD9dGu%2FGTiQk3kSXrnWWTedNZGkY1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;366&quot; height=&quot;265&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;265&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>bfs</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/63</guid>
      <comments>https://kimbyeongnyeon.tistory.com/63#entry63comment</comments>
      <pubDate>Sun, 1 Feb 2026 16:41:39 +0900</pubDate>
    </item>
    <item>
      <title>동전 0</title>
      <link>https://kimbyeongnyeon.tistory.com/62</link>
      <description>&lt;h1&gt;동전 0&lt;/h1&gt;
&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;준규가 가지고 있는 동전은 총 N종류이고, 각각의 동전을 매우 많이 가지고 있다.&lt;/p&gt;
&lt;p&gt;동전을 적절히 사용해서 그 가치의 합을 K로 만들려고 한다. 이때 필요한 동전 개수의 최솟값을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h2&gt;예제 입력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;10 4200
1
5
10
50
100
500
1000
5000
10000
50000&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;예제 출력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;6&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const fs = require(&amp;quot;fs&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const input = fs
  .readFileSync(process.platform === &amp;quot;linux&amp;quot; ? &amp;quot;dev/stdin&amp;quot; : &amp;quot;input.txt&amp;quot;)
  .toString()
  .trim()
  .split(&amp;quot;\n&amp;quot;);

const solution = (input) =&amp;gt; {
  let [N, K] = input.shift().split(&amp;quot; &amp;quot;).map(Number);
  // 동전 내림차순으로 정렬
  const coins = input.map(Number).sort((a, b) =&amp;gt; b - a);
  let cnt = 0;
  for (let coin of coins) {
    // 카운트에 금액이 높은 순서부터 몫을 구한 후 누적
    cnt += Math.floor(K / coin);
    // K 는 동전의 몫을 구한 나머지로 바꿔주기
    K = K % coin;
  }

  console.log(cnt)
};
solution(input);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;아이디어 / 접근법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;내림차순 정렬&lt;/li&gt;
&lt;li&gt;높은 동전부터 K에서 나올 수 있는 몫 계산&lt;/li&gt;
&lt;li&gt;K 값 현재 동전에서의 나머지 값으로 재할당&lt;/li&gt;
&lt;li&gt;카운트 리턴&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;후기&lt;/h3&gt;
&lt;p&gt;그리디 문제였고 오랜만에 그리디 풀어봤는데 생각보다 어려웠음 아침에 머리 안돌아갈 때 풀어서 그런 지는 몰라도 뭔가 잘 안된 것 같았음&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>그리디</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/62</guid>
      <comments>https://kimbyeongnyeon.tistory.com/62#entry62comment</comments>
      <pubDate>Sun, 1 Feb 2026 16:38:09 +0900</pubDate>
    </item>
    <item>
      <title>행렬의 곱셈</title>
      <link>https://kimbyeongnyeon.tistory.com/61</link>
      <description>&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.&lt;/p&gt;
&lt;h3&gt;제한 조건&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;행렬 arr1, arr2의 행과 열의 길이는 2 이상 100 이하입니다.&lt;/li&gt;
&lt;li&gt;행렬 arr1, arr2의 원소는 -10 이상 20 이하인 자연수입니다.&lt;/li&gt;
&lt;li&gt;곱할 수 있는 배열만 주어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;입출력 예&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;arr1    arr2    return
[[1, 4], [3, 2], [4, 1]]    [[3, 3], [3, 3]]    [[15, 15], [15, 15], [15, 15]]
[[2, 3, 2], [4, 2, 4], [3, 1, 4]]    [[5, 4, 3], [2, 4, 1], [3, 1, 1]]    [[22, 22, 11], [36, 28, 18], [29, 20, 14]]&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;function solution(arr1, arr2) {
  const n = arr1.length;
  const m = arr2.length;
  const k = arr2[0].length;

  const result = Array.from({ length: n }, () =&amp;gt; Array(k).fill(0));

  for (let i = 0; i &amp;lt; n; i++) {
    for (let j = 0; j &amp;lt; k; j++) {
        for (let t = 0; t &amp;lt; m; t++) {
            result[i][j] += arr1[i][t] * arr2[t][j]
        }
    }
  }

  return result
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;아이디어&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;arr1, arr2의 길이와 arr2[0]의 길이 저장&lt;/li&gt;
&lt;li&gt;반복문 돌려가면서 arr1과 arr2의 곱을 누적합&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>알고리즘</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/61</guid>
      <comments>https://kimbyeongnyeon.tistory.com/61#entry61comment</comments>
      <pubDate>Sun, 1 Feb 2026 16:36:07 +0900</pubDate>
    </item>
    <item>
      <title>배달</title>
      <link>https://kimbyeongnyeon.tistory.com/60</link>
      <description>&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;N개의 마을로 이루어진 나라가 있습니다. 이 나라의 각 마을에는 1부터 N까지의 번호가 각각 하나씩 부여되어 있습니다. 각 마을은 양방향으로 통행할 수 있는 도로로 연결되어 있는데, 서로 다른 마을 간에 이동할 때는 이 도로를 지나야 합니다. 도로를 지날 때 걸리는 시간은 도로별로 다릅니다. 현재 1번 마을에 있는 음식점에서 각 마을로 음식 배달을 하려고 합니다. 각 마을로부터 음식 주문을 받으려고 하는데, N개의 마을 중에서 K 시간 이하로 배달이 가능한 마을에서만 주문을 받으려고 합니다. 다음은 N = 5, K = 3인 경우의 예시입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8o7fq/dJMcadHA5dP/md4dXR1LfKyzkxWZ6uAaQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8o7fq/dJMcadHA5dP/md4dXR1LfKyzkxWZ6uAaQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8o7fq/dJMcadHA5dP/md4dXR1LfKyzkxWZ6uAaQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8o7fq%2FdJMcadHA5dP%2Fmd4dXR1LfKyzkxWZ6uAaQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;212&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 그림에서 1번 마을에 있는 음식점은 [1, 2, 4, 5] 번 마을까지는 3 이하의 시간에 배달할 수 있습니다. 그러나 3번 마을까지는 3시간 이내로 배달할 수 있는 경로가 없으므로 3번 마을에서는 주문을 받지 않습니다. 따라서 1번 마을에 있는 음식점이 배달 주문을 받을 수 있는 마을은 4개가 됩니다.&lt;br&gt;마을의 개수 N, 각 마을을 연결하는 도로의 정보 road, 음식 배달이 가능한 시간 K가 매개변수로 주어질 때, 음식 주문을 받을 수 있는 마을의 개수를 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;p&gt;제한 사항&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;마을의 개수 N은 1 이상 50 이하의 자연수입니다.&lt;/li&gt;
&lt;li&gt;road의 길이(도로 정보의 개수)는 1 이상 2,000 이하입니다.&lt;/li&gt;
&lt;li&gt;road의 각 원소는 마을을 연결하고 있는 각 도로의 정보를 나타냅니다.&lt;/li&gt;
&lt;li&gt;road는 길이가 3인 배열이며, 순서대로 (a, b, c)를 나타냅니다.&lt;ul&gt;
&lt;li&gt;a, b(1 ≤ a, b ≤ N, a != b)는 도로가 연결하는 두 마을의 번호이며, c(1 ≤ c ≤ 10,000, c는 자연수)는 도로를 지나는데 걸리는 시간입니다.&lt;/li&gt;
&lt;li&gt;두 마을 a, b를 연결하는 도로는 여러 개가 있을 수 있습니다.&lt;/li&gt;
&lt;li&gt;한 도로의 정보가 여러 번 중복해서 주어지지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;K는 음식 배달이 가능한 시간을 나타내며, 1 이상 500,000 이하입니다.&lt;/li&gt;
&lt;li&gt;임의의 두 마을간에 항상 이동 가능한 경로가 존재합니다.&lt;/li&gt;
&lt;li&gt;1번 마을에 있는 음식점이 K 이하의 시간에 배달이 가능한 마을의 개수를 return 하면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;입출력 예&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;N    road    K    result
5    [[1,2,1],[2,3,3],[5,2,2],[1,4,2],[5,3,1],[5,4,2]]    3    4
6    [[1,2,1],[1,3,2],[2,3,2],[3,4,3],[3,5,2],[3,5,3],[5,6,1]]    4    4&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;function solution(N, road, K) {
  var answer = 0;
  const graph = Array.from({ length: N + 1 }, () =&amp;gt; []);

  for (let i = 0; i &amp;lt; road.length; i++) {
    const [a, b, c] = road[i];
    graph[a].push({ to: b, cost: c });
    graph[b].push({ to: a, cost: c });
  }

  const dist = Array(N + 1).fill(Infinity);
  const visited = Array(N + 1).fill(false);

  dist[1] = 0
    visited[1] = true

  const dijkstra = () =&amp;gt; {
    let result = 0;
    for (let i = 0; i &amp;lt; N; i++) {
      let now = -1;
      let min = Infinity;

      for (let j = 1; j &amp;lt;= N; j++) {
        if (!visited[j] &amp;amp;&amp;amp; dist[j] &amp;lt; min) {
          min = dist[j];
          now = j;
        }
      }

      if (now === -1) break;
      visited[now] = true;
      for (const next of graph[now]) {
        const newCost = dist[now] + next.cost;
        if (newCost &amp;lt; dist[next.to]) {
          dist[next.to] = newCost;
        }
      }
    }
    for (const d of dist) {
      if (d &amp;lt;= K) result++;
    }
    return result;
  };
  answer = dijkstra();
  return answer;
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;아이디어 / 접근법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;양방향 그래프 만들기&lt;/li&gt;
&lt;li&gt;시작 마을 거리 0으로 초기화&lt;/li&gt;
&lt;li&gt;다익스트라 실행&lt;/li&gt;
&lt;li&gt;방문하지 않았고, 거리가 최소값이라면 최신화&lt;/li&gt;
&lt;li&gt;마을에서 다음 마을에 갈 때 필요한 최소값을 dist 배열에 저장&lt;/li&gt;
&lt;li&gt;dist 배열 중 K 보다 작은 값들이 있으면 카운팅 후 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;후기&lt;/h3&gt;
&lt;p&gt;문제를 보자마자 다익스트라로 풀어야겠다고 생각했다. 여러 노드들에서 최소비용을 체크할 필요 없고 하나의 노드(1번 마을)에서만 체크하면 되기 때문에 반복문 자체도 하나가 줄어들기 때문에 일단 기본 배열로 다익스트라를 짜봤는데 다행히 시간 초과 없이 잘 됐다&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>다익스트라</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/60</guid>
      <comments>https://kimbyeongnyeon.tistory.com/60#entry60comment</comments>
      <pubDate>Sun, 1 Feb 2026 16:33:59 +0900</pubDate>
    </item>
    <item>
      <title>한수</title>
      <link>https://kimbyeongnyeon.tistory.com/59</link>
      <description>&lt;h1&gt;한수&lt;/h1&gt;
&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h2&gt;예제 입력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;110&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;예제 출력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;99&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const fs = require(&amp;quot;fs&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const input = fs
  .readFileSync(
    process.platform === &amp;quot;linux&amp;quot;
      ? &amp;quot;dev/stdin&amp;quot;
      : path.join(__dirname, &amp;quot;input.txt&amp;quot;)
  )
  .toString()
  .trim()
  .split(&amp;quot;\n&amp;quot;);

const solution = (input) =&amp;gt; {
  const x = Number(input[0]);

  const solve = (n) =&amp;gt; {
    if (n &amp;lt; 100) return true;
    const digit = n.toString().split(&amp;quot;&amp;quot;).map(Number);
    const diff = digit[1] - digit[0];

    for (let i = 2; i &amp;lt; digit.length; i++) {
      if (digit[i] - digit[i - 1] !== diff) return false;
    }
    return true;
  };
  result = 0;
  for (let i = 1; i &amp;lt; x + 1; i++) {
    if (solve(i)) result++;
  }
  console.log(result);
};
solution(input);&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;아이디어&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;1 부터 x 까지 반복&lt;/li&gt;
&lt;li&gt;해당 숫자가 100 이하라면 바로 true 반환&lt;/li&gt;
&lt;li&gt;자리수를 나눈 뒤 먼저 1번 인덱스에서 0번 인덱스를 빼서 등차를 구함&lt;/li&gt;
&lt;li&gt;다음 값 탐색 하면서 그 값이 아니라면 false 반환&lt;/li&gt;
&lt;li&gt;true 인 경우 result 에 추가&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;후기&lt;/h2&gt;
&lt;p&gt;코테 대비 문제 7&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>브루트 포스</category>
      <category>수학</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/59</guid>
      <comments>https://kimbyeongnyeon.tistory.com/59#entry59comment</comments>
      <pubDate>Sun, 1 Feb 2026 16:29:39 +0900</pubDate>
    </item>
    <item>
      <title>카드 놓기</title>
      <link>https://kimbyeongnyeon.tistory.com/58</link>
      <description>&lt;h1&gt;카드 놓기&lt;/h1&gt;
&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;상근이는 카드 n(4 ≤ n ≤ 10)장을 바닥에 나란히 놓고 놀고있다. 각 카드에는 1이상 99이하의 정수가 적혀져 있다. 상근이는 이 카드 중에서 k(2 ≤ k ≤ 4)장을 선택하고, 가로로 나란히 정수를 만들기로 했다. 상근이가 만들 수 있는 정수는 모두 몇 가지일까?&lt;/p&gt;
&lt;p&gt;예를 들어, 카드가 5장 있고, 카드에 쓰여 있는 수가 1, 2, 3, 13, 21라고 하자. 여기서 3장을 선택해서 정수를 만들려고 한다. 2, 1, 13을 순서대로 나열하면 정수 2113을 만들 수 있다. 또, 21, 1, 3을 순서대로 나열하면 2113을 만들 수 있다. 이렇게 한 정수를 만드는 조합이 여러 가지 일 수 있다.&lt;/p&gt;
&lt;p&gt;n장의 카드에 적힌 숫자가 주어졌을 때, 그 중에서 k개를 선택해서 만들 수 있는 정수의 개수를 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;h2&gt;예제 입력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;4
2
1
2
12
1&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;예제 출력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;7&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const fs = require(&amp;quot;fs&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const input = fs
  .readFileSync(
    process.platform === &amp;quot;linux&amp;quot;
      ? &amp;quot;dev/stdin&amp;quot;
      : path.join(__dirname, &amp;quot;input.txt&amp;quot;)
  )
  .toString()
  .trim()
  .split(&amp;quot;\n&amp;quot;);

const solution = (input) =&amp;gt; {
  let idx = 0;
  const arr = [];
  const N = Number(input[idx++]);
  const K = Number(input[idx++]);
  for (let i = 0; i &amp;lt; N; i++) {
    arr.push(Number(input[idx++]));
  }

  const set = new Set();
  const visited = Array.from({ length: N }, () =&amp;gt; false);

  const dfs = (depth, num) =&amp;gt; {
    if (depth === K) {
      set.add(Number(num));
      return;
    }
    for (let i = 0; i &amp;lt; N; i++) {
      if (visited[i] === false) {
        visited[i] = true;
        dfs(depth + 1, num.toString() + arr[i].toString());
        visited[i] = false;
      }
    }
  };
  dfs(0, &amp;quot;&amp;quot;);
  console.log(set.size);
};
solution(input);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;아이디어&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;동일한 수 넣지 않도록 Set 생성&lt;/li&gt;
&lt;li&gt;재귀 함수를 돌려가면서 depth가 K 에 도달하면 set에 추가&lt;/li&gt;
&lt;li&gt;재귀 함수 매개변수를 문자열로 받아서 1 + 1 = 11 과 같이 하도록 함&lt;/li&gt;
&lt;li&gt;재귀 호출 끝나면 visited 배열 원복&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;후기&lt;/h3&gt;
&lt;p&gt;코테 대비 문제 6&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>백트래킹</category>
      <category>재귀</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/58</guid>
      <comments>https://kimbyeongnyeon.tistory.com/58#entry58comment</comments>
      <pubDate>Mon, 26 Jan 2026 21:05:52 +0900</pubDate>
    </item>
    <item>
      <title>아기상어2</title>
      <link>https://kimbyeongnyeon.tistory.com/57</link>
      <description>&lt;h1&gt;아기 상어 2&lt;/h1&gt;
&lt;h2&gt;문제 설명&lt;/h2&gt;
&lt;p&gt;N×M 크기의 공간에 아기 상어 여러 마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 아기 상어가 최대 1마리 존재한다.&lt;/p&gt;
&lt;p&gt;어떤 칸의 안전 거리는 그 칸과 가장 거리가 가까운 아기 상어와의 거리이다. 두 칸의 거리는 하나의 칸에서 다른 칸으로 가기 위해서 지나야 하는 칸의 수이고, 이동은 인접한 8방향(대각선 포함)이 가능하다.&lt;/p&gt;
&lt;p&gt;안전 거리가 가장 큰 칸을 구해보자.&lt;/p&gt;
&lt;h2&gt;예제 입력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;5 4
0 0 1 0
0 0 0 0
1 0 0 0
0 0 0 0
0 0 0 1&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;예제 출력&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;2&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;문제 풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const fs = require(&amp;quot;fs&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const input = fs
  .readFileSync(
    process.platform === &amp;quot;linux&amp;quot;
      ? &amp;quot;dev/stdin&amp;quot;
      : path.join(__dirname, &amp;quot;input.txt&amp;quot;)
  )
  .toString()
  .trim()
  .split(&amp;quot;\n&amp;quot;);

const solution = (input) =&amp;gt; {
  const dx = [-1, 1, 0, 0, -1, 1, 1, -1];
  const dy = [0, 0, -1, 1, -1, -1, 1, 1];
  const [N, M] = input[0].split(&amp;quot; &amp;quot;).map(Number);
  const arr = input.slice(1).map((line) =&amp;gt; line.split(&amp;quot; &amp;quot;).map(Number));

  const bfs = () =&amp;gt; {
    let queue = [];
    let head = 0;
    for (let i = 0; i &amp;lt; N; i++) {
      for (let j = 0; j &amp;lt; M; j++) {
        if (arr[i][j] === 1) queue.push([i, j]);
      }
    }

    while (queue.length &amp;gt; head) {
      const [x, y] = queue[head++];
      for (let k = 0; k &amp;lt; 8; k++) {
        let nx = x + dx[k];
        let ny = y + dy[k];
        if (0 &amp;lt;= nx &amp;amp;&amp;amp; nx &amp;lt; N &amp;amp;&amp;amp; 0 &amp;lt;= ny &amp;amp;&amp;amp; ny &amp;lt; M) {
          if (arr[nx][ny] === 0) {
            arr[nx][ny] = arr[x][y] + 1;
            queue.push([nx, ny]);
          }
        }
      }
    }
  };

  let mx = 0;
  bfs();

  for (let i = 0; i &amp;lt; N; i++) {
    for (let j = 0; j &amp;lt; M; j++) {
      mx = Math.max(mx, arr[i][j]);
    }
  }
  console.log(mx - 1);
};
solution(input);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;아이디어 / 접근법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;반복문을 돌려서 상어의 좌표 다 넣어주기&lt;/li&gt;
&lt;li&gt;8방향 델타 탐색 이후 원본 배열 갱신 후 queue에 추가&lt;/li&gt;
&lt;li&gt;최댓값 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;후기&lt;/h3&gt;
&lt;p&gt;다시 BFS 감을 잡고자 푼 문제인데 별로 어려운 것은 없었고 상어들의 좌표를 다 queue에 넣어놓고 시작해야 한다는 점이 좀 달랐음&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>bfs</category>
      <author>kimbyeongnyeon</author>
      <guid isPermaLink="true">https://kimbyeongnyeon.tistory.com/57</guid>
      <comments>https://kimbyeongnyeon.tistory.com/57#entry57comment</comments>
      <pubDate>Mon, 26 Jan 2026 21:00:58 +0900</pubDate>
    </item>
  </channel>
</rss>