<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>공부중</title>
    <link>https://nnindd.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 22 Jun 2026 23:33:01 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>민딛</managingEditor>
    <image>
      <title>공부중</title>
      <url>https://tistory1.daumcdn.net/tistory/5443085/attach/753f57a63d3c4d4086d5b46b11b634e6</url>
      <link>https://nnindd.tistory.com</link>
    </image>
    <item>
      <title>[알고리즘 정리] 정렬</title>
      <link>https://nnindd.tistory.com/91</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;기본 정렬 알고리즘&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;버블 정렬&lt;/li&gt;
&lt;li&gt;삽입 정렬&lt;/li&gt;
&lt;li&gt;선택 정렬&lt;/li&gt;
&lt;li&gt;합병 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;버블 정렬&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인접한 두개의 원소&lt;/b&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;시간복잡도는 O&lt;span style=&quot;color: #202122; text-align: start;&quot;&gt;(&lt;/span&gt;n^2&lt;span style=&quot;color: #202122; text-align: start;&quot;&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699626428086&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private static void bubbleSort(int[] a) {
    for (int i = 0; i &amp;lt; a.length - 1; i++) {
        for (int j = 0; j &amp;lt; a.length - i - 1; j++) {
            if (a[j] &amp;gt; a[j + 1]) {
                int temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;삽입 정렬&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;두번째 원소부터 앞의 원소와 비교&lt;/b&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;시간복잡도는 O&lt;span style=&quot;color: #202122; text-align: start;&quot;&gt;(&lt;/span&gt;n&lt;span style=&quot;color: #202122; text-align: start;&quot;&gt;), 역순으로 정렬된 배열이라면 O(n^2)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699627199497&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private static void insertionSort(int[] a) {
    for (int i = 1; i &amp;lt; a.length; i++) {
        int num = a[i]; //비교할 원소
        int j = i - 1; //앞의 원소

        while (j &amp;gt;= 0 &amp;amp;&amp;amp; num &amp;lt; a[j]) { //앞의 원소가 더 크다면 바꿔준다
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = num;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;선택 정렬&lt;/h4&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;불안정 정렬에 속한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도는 O(n^2)&lt;/p&gt;
&lt;pre id=&quot;code_1699627732915&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private static void selectionSort(int[] a) {
    for (int i = 0; i &amp;lt; a.length; i++) {
        int now = i; //전환할 인덱스

        for (int j = i + 1; j &amp;lt; a.length; j++) {
            if (a[j] &amp;lt; a[now]) //최소값이 담긴 인덱스 찾기
                now = j;
        }

        int temp = a[now];
        a[now] = a[i];
        a[i] = temp;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;병합 정렬&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분할 정복 알고리즘.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;divide and conquer의 과정을 거친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 크기가 1이 될 때까지 나누고, 합치는 과정.&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;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: -webkit-center;&quot;&gt;O(nlogn)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699629841893&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private static void mergeSort(int[] a, int left, int right) {
    //main 함수 호출 부분
    //mergeSort(arr, 0, arr.length - 1);
    if (left &amp;lt; right) {
        int mid = (left + right) / 2;

        mergeSort(a, left, mid);
        mergeSort(a, mid + 1, right);

        merge(a, left, mid, right);
    }
}

private static void merge(int[] a, int left, int mid, int right) {
    int[] temp = a.clone();

    int i = left; //왼쪽 배열의 시작 인덱스
    int j = mid + 1; //오른쪽 배열의 시작 인덱스
    int idx = left; //정렬된 값을 넣을 위치 인덱스

    //왼쪽 배열과 오른쪽 배열 비교하며 작은 원소부터 추가
    while (i &amp;lt;= mid &amp;amp;&amp;amp; j &amp;lt;= right) {
        if (temp[i] &amp;lt; temp[j]) {
            a[idx++] = temp[i++];
        } else {
            a[idx++] = temp[j++];
        }
    }

    if (mid &amp;lt; i) { //오른쪽 남은 배열 채우기
        for (int k = j; k &amp;lt;= right; k++) {
            a[idx++] = temp[k];
        }
    } else { //왼쪽 남은 배열 채우기
        for (int k = i; k &amp;lt;= mid; k++) {
            a[idx++] = temp[k];
        }
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>CS/Algorithm</category>
      <category>알고리즘</category>
      <category>정렬</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/91</guid>
      <comments>https://nnindd.tistory.com/91#entry91comment</comments>
      <pubDate>Sat, 11 Nov 2023 00:24:18 +0900</pubDate>
    </item>
    <item>
      <title>[CodeTree Java] 메이즈 러너</title>
      <link>https://nnindd.tistory.com/90</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/training-field/frequent-problems/problems/maze-runner/description?page=3&amp;amp;pageSize=20&quot;&gt;https://www.codetree.ai/training-field/frequent-problems/problems/maze-runner/description?page=3&amp;amp;pageSize=20&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;모든 사람이 탈출하고 나서 회전하는 경우&lt;/li&gt;
&lt;li&gt;배열을 회전하고 나서 사람의 위치를 갱신하는 경우&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번은 모두 탈출했는지 탐색하고 나서 이동과 회전을 진행했는데, 회전할 정사각형의 범위를 0으로 초기화 해줘야 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번은 인덱스 매칭으로 회전한 위치를 구해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 맵을 회전할때에는&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사람과 출구 위치를 맵에 넣음&lt;/li&gt;
&lt;li&gt;회전 범위에 따라 회전&lt;/li&gt;
&lt;li&gt;회전하면서 사람 위치와 출구라면 새로운 위치로 갱신해줌&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 로직이었는데 다음과 같은 예시에서 문제가 생겼다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 25.4651%; height: 165px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;사람1명&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;사람2명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;9&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;출구&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 위의 로직을 따르면 사람 1명을 먼저 갱신하고 사람 2명의 위치에서 모든 사람의 위치가 하나로 갱신되는 문제가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 다음과 같이 로직을 변경했다&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사람 수만큼 반복문&lt;/li&gt;
&lt;li&gt;현재 사람이 탈출하지 않았고, 회전 범위에 있는지 확인&lt;/li&gt;
&lt;li&gt;회전 범위에 있다면 (0,0) 기준으로 위치를 이동&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[x][y] -&amp;gt; [y][박스크기 - x - 1]&lt;/code&gt; 공식 적용&lt;/li&gt;
&lt;li&gt;기준점으로 위치 이동한 만큼 다시 더해줌&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분을 조심해서 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1693211058222&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    static class Pos {
        int x, y;
        boolean isOut;

        public Pos(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public Pos(int x, int y, boolean isOut) {
            this.x = x;
            this.y = y;
            this.isOut = isOut;
        }
    }

    static int N, M, K, map[][], copy[][], total;
    static Pos exit; //출구 위치
    static int bx, by, boxSize; //회전할 박스 시작행열, 사이즈 저장
    static Pos[] p; //사람들 좌표 저장

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        N = Integer.parseInt(tokens.nextToken()); //맵
        M = Integer.parseInt(tokens.nextToken()); //사람
        K = Integer.parseInt(tokens.nextToken()); //게임시간

        map = new int[N][N];
        p = new Pos[M];
        total = 0;

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; N; j++) {
                map[i][j] = Integer.parseInt(tokens.nextToken());
            }
        }

        for (int i = 0; i &amp;lt; M; i++) {
            tokens = new StringTokenizer(br.readLine());
            p[i] = new Pos(Integer.parseInt(tokens.nextToken()) - 1,
                    Integer.parseInt(tokens.nextToken()) - 1,
                    false);
        }

        tokens = new StringTokenizer(br.readLine());
        exit = new Pos(Integer.parseInt(tokens.nextToken()) - 1,
                Integer.parseInt(tokens.nextToken()) - 1);
        //end input

        while (K-- &amp;gt; 0) {
            //모든 참가자가 탈출했는지 확인
            if (isAllOut()) break;

            for (int i = 0; i &amp;lt; M; i++) {
                movePeople(i); //모든 참가자 이동
                //이동했는데 출구인지 확인
                if (p[i].x == exit.x &amp;amp;&amp;amp; p[i].y == exit.y) {
                    p[i].isOut = true;
                }
            }

            bx = by = boxSize = 0; //모두 탈출하고 회전시킬 경우
            findRect(); //상자 사이즈 찾음

            rotateRect(); //미로 회전
        }

        exit.x++;
        exit.y++;
        System.out.println(total);
        System.out.println(exit.x + &quot; &quot; + exit.y);
    }

    private static boolean isAllOut() {
        for (int i = 0; i &amp;lt; M; i++) {
            if (!p[i].isOut) return false;
        }
        return true;
    }

    private static void rotateRect() {
        //맵 복사
        copy = new int[N][];
        for (int i = 0; i &amp;lt; N; i++) {
            copy[i] = Arrays.copyOfRange(map[i], 0, N);
        }

        //복사한 값을 원본에 돌려서 넣기
        for (int i = bx, x = by; i &amp;lt; bx + boxSize; i++, x++) {
            for (int j = by, y = bx + boxSize - 1; j &amp;lt; by + boxSize; j++, y--) {
                map[i][j] = copy[y][x];

                //내구도 감소
                if (isArea(map[i][j], 1, 10))
                    map[i][j]--;
            }
        }

        //출구 위치 변경
        if (isArea(exit.x, bx, bx + boxSize) &amp;amp;&amp;amp; isArea(exit.y, by, by + boxSize)) {
            //(0,0) 기준으로 옮김
            int nx = exit.x - bx;
            int ny = exit.y - by;

            //회전시킴
            //20 -&amp;gt; 00
            //10 -&amp;gt; 01
            //00 -&amp;gt; 02
            //[x][y] -&amp;gt; [y][size-x-1]
            exit.x = ny + bx;
            exit.y = boxSize - nx - 1 + by;
        }

        //사람 위치 변경
        for (int i = 0; i &amp;lt; M; i++) {
            if (p[i].isOut) continue;

            if (isArea(p[i].x, bx, bx + boxSize) &amp;amp;&amp;amp; isArea(p[i].y, by, by + boxSize)) {
                int nx = p[i].x - bx;
                int ny = p[i].y - by;

                p[i].x = ny + bx;
                p[i].y = boxSize - nx - 1 + by;
            }
        }
    }

    private static void findRect() {
        for (int size = 2; size &amp;lt;= N; size++) { //만들 수 있는 사각형
            for (int i = 0; i &amp;lt; N - size + 1; i++) {
                for (int j = 0; j &amp;lt; N - size + 1; j++) {
                    //출구가 있는지 확인
                    if (!(isArea(exit.x, i, i + size) &amp;amp;&amp;amp; isArea(exit.y, j, j + size))) {
                        continue;
                    }

                    boolean flag = false;
                    //사람이 있는지 확인
                    for (int m = 0; m &amp;lt; M; m++) {
                        if (p[m].isOut) continue; //출구에 있는 참가자 제외

                        Pos now = p[m];
                        if (i &amp;lt;= now.x &amp;amp;&amp;amp; now.x &amp;lt; i + size
                                &amp;amp;&amp;amp; j &amp;lt;= now.y &amp;amp;&amp;amp; now.y &amp;lt; j + size) {
                            flag = true;
                        }
                    }

                    if (flag) {
                        bx = i;
                        by = j;
                        boxSize = size;
                        return;
                    }

                }//end j

            }//end i

        }//end size
    }

    private static void movePeople(int idx) {
        Pos now = p[idx];

        //이미 출구인 경우
        if (now.isOut) return;

        //행이 다르다면 상하로 움직이기
        if (now.x != exit.x) {
            int nx = now.x;
            int ny = now.y;

            if (nx &amp;gt; exit.x) nx--; //위로 이동
            else nx++; //아래로 이동

            if (isRange(nx, ny) &amp;amp;&amp;amp; map[nx][ny] == 0) {
                //움직일 수 있음
                now.x = nx;
                now.y = ny;
                p[idx] = now;
                total++;
                return;
            }
        }

        //열이 다르다면 좌우로 움직이기
        if (now.y != exit.y) {
            int nx = now.x;
            int ny = now.y;

            if (ny &amp;gt; exit.y) ny--; //좌로 이동
            else ny++; //우로 이동

            if (isRange(nx, ny) &amp;amp;&amp;amp; map[nx][ny] == 0) {
                now.x = nx;
                now.y = ny;
                p[idx] = now;
                total++;
            }
        }
    }

    private static boolean isArea(int x, int min, int max) {
        if (min &amp;lt;= x &amp;amp;&amp;amp; x &amp;lt; max) return true;
        return false;
    }

    private static boolean isRange(int x, int y) {
        if (x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= N) return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/CodeTree</category>
      <category>시뮬레이션</category>
      <category>코드트리</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/90</guid>
      <comments>https://nnindd.tistory.com/90#entry90comment</comments>
      <pubDate>Mon, 28 Aug 2023 17:32:53 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 1036 36진수</title>
      <link>https://nnindd.tistory.com/89</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1036&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1036&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해하고 푸는데 한참 걸렸다. 진짜.. 진짜 오래 걸렸다 진짜...........&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;36진법으로 변환할 때 0-9, A-Z에서 해당하는 자리수를 Z로 변환했을 때 가장 큰 차이가 나는 것을 선택해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말로 풀어서 설명하기 어려운데, 예를 들어서 예제의 HELLO는 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 33.2558%; height: 135px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.3593%; height: 17px;&quot;&gt;H&lt;/td&gt;
&lt;td style=&quot;width: 78.6407%; height: 17px;&quot;&gt;17 * 36^4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.3593%; height: 17px;&quot;&gt;E&lt;/td&gt;
&lt;td style=&quot;width: 78.6407%; height: 17px;&quot;&gt;14 * 36^3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.3593%; height: 17px;&quot;&gt;L&lt;/td&gt;
&lt;td style=&quot;width: 78.6407%; height: 17px;&quot;&gt;21 * 36^2 + 21 * 36^1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.3593%; height: 17px;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 78.6407%; height: 17px;&quot;&gt;24 * 36^0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 Z로 변환했을 때 차이가 가장 큰 값을 찾으려면 아래와 같이 변환하면 된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 33.2558%; height: 135px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;H&lt;/td&gt;
&lt;td&gt;(35-17) * 36^4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;(35-14) * 36^3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L&lt;/td&gt;
&lt;td&gt;(35-21) * 36^2 + (35-21) * 36^1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;(35-24) * 36^0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 0-9, A-Z 값을 저장할 배열을 만들어주고, 해당 인덱스에 맞게 위의 표에 맞게 자리수를 넣어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열을 정렬해주고 난 후 가장 차이가 큰 수를 K개 더해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 예로 들면,&lt;/p&gt;
&lt;pre id=&quot;code_1689826031284&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 1
b = 2
z = 10

a + b = 3 //총 합으로 사용

z - a = 9
z - b = 8

이때 a를 선택한다.

총합에 z-a의 차이를 더해주면 a + b -&amp;gt; 3 + (z - a) = 3 + 9 = 12가 된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 예시로 N만큼 입력을 받고 36진수로 변환해서 일단 모든 숫자의 총합을 구해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Z로 변환했을 때 가장 큰 차이를 가지는 상위 K개가 가지고 있는 차이값을 총합에 더해주면 구하고자 하는 최대값이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 어떤 문자를 바꿀 것인지는 몰라도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바의 long 타입은 50자를 받지 못하기 때문에 BigInteger를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문게시판에서 반례를 참고했다&lt;/p&gt;
&lt;pre id=&quot;code_1689825777428&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2
99999999999999999999999999999999999999999999999999
1
1

답
100000000000000000000000000000000000000000000000000&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1689825338644&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());

        //0) 초기화
        // 0-9, A-Z의 36진수 값을 저장할 배열 설정
        BigInteger[] digit = new BigInteger[36];
        Arrays.fill(digit, BigInteger.ZERO); //초기화

        //총합
        BigInteger sum = BigInteger.ZERO;

        for (int i = 0; i &amp;lt; N; i++) {
            String str = br.readLine();
            BigInteger cur = new BigInteger(str, 36); //36진수로 변환

            //1) 각 36진수를 총합에 더해줌
            sum = sum.add(cur);

            //2) 한글자씩 Z로 변환했을 때 가중치를 저장
            //ex) YZ라면, digit[Y] += (35 - Y) * 36^1을 저장함
            BigInteger pow = BigInteger.ONE; //지수 값
            for (int j = str.length() - 1; j &amp;gt;= 0; j--) {
                int idx = str.charAt(j) &amp;lt;= '9' ? str.charAt(j) - '0' : str.charAt(j) - 'A' + 10; //digit에 저장할 인덱스 설정
                digit[idx] = digit[idx].add(pow.multiply(BigInteger.valueOf(35 - idx)));
                pow = pow.multiply(BigInteger.valueOf(36)); //다음 자리수로
            }
        }

        //3) digit을 정렬하고 내림차순으로 사용해서 K만큼 더해줌
        //ex) 1+2 = 3을 10+2=12로 변경했을 때, 10-1의 차이인 9만큼 더해줘야 총 합이 됨
        int K = Integer.parseInt(br.readLine());
        Arrays.sort(digit);
        int cnt = 0;
        for (int i = 35; i &amp;gt;= 0 ; i--) {
            if(cnt == K) break;
            sum = sum.add(digit[i]);
            cnt++;
        }

        //4) 출력
        System.out.println(sum.toString(36).toUpperCase());

    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 하나하나 전부 36 -&amp;gt; 10 -&amp;gt; 36 변환해가면서 구했는데 로직 자체가 틀렸었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 수 연산같은걸 생각해야 하는 문제가 아직도 어렵다...&lt;/p&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>그리디</category>
      <category>문자열</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/89</guid>
      <comments>https://nnindd.tistory.com/89#entry89comment</comments>
      <pubDate>Thu, 20 Jul 2023 13:11:27 +0900</pubDate>
    </item>
    <item>
      <title>[Git] commit 내역에 큰 파일 기록 지우기</title>
      <link>https://nnindd.tistory.com/88</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;GitLab에서 GitHub으로 레포지토리를 미러링시 100MB를 넘는 파일이 있다면 에러가 나며 미러링이 안 되는 문제가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;&lt;code&gt;File {파일명} is 105.41 MB; this exceeds GitHub's file size limit of 100.00 MB \nremote: error: GH001: Large files detected.&lt;/code&gt;&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1688104778032&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git filter-branch --tree-filter 'rm -f 파일명' HEAD&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 명령어를 실행하면 아래와 같이 뜬다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2qyeG/btslTUF3gqW/7nGbuyB2hpRiilgDEDIjL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2qyeG/btslTUF3gqW/7nGbuyB2hpRiilgDEDIjL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2qyeG/btslTUF3gqW/7nGbuyB2hpRiilgDEDIjL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2qyeG%2FbtslTUF3gqW%2F7nGbuyB2hpRiilgDEDIjL0%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;1456&quot; height=&quot;306&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적으로 되었으면 원격 레포지토리에 push 해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1688106118137&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push 원격remote명 브랜치명 --force
ex) git push github master --force&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Project</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/88</guid>
      <comments>https://nnindd.tistory.com/88#entry88comment</comments>
      <pubDate>Fri, 30 Jun 2023 15:22:18 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 14499 주사위 굴리기</title>
      <link>https://nnindd.tistory.com/87</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14499&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14499&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&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;table style=&quot;border-collapse: collapse; width: 57.093%; height: 89px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;기본&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;동쪽&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;서쪽&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;북쪽&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;남쪽&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 70px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 70px;&quot;&gt;&amp;nbsp; &amp;nbsp;2&lt;br /&gt;4 1 3&lt;br /&gt;&amp;nbsp; &amp;nbsp;5&lt;br /&gt;&amp;nbsp; &amp;nbsp;6&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 70px;&quot;&gt;&amp;nbsp; &amp;nbsp;2&lt;br /&gt;6 4 1&lt;br /&gt;&amp;nbsp; &amp;nbsp;5&lt;br /&gt;&amp;nbsp; &amp;nbsp;3&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 70px;&quot;&gt;&amp;nbsp; &amp;nbsp;2&lt;br /&gt;1 3 6&lt;br /&gt;&amp;nbsp; &amp;nbsp;5&lt;br /&gt;&amp;nbsp; &amp;nbsp;4&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 70px;&quot;&gt;&amp;nbsp; &amp;nbsp;1&lt;br /&gt;4 5 3&lt;br /&gt;&amp;nbsp; &amp;nbsp;6&lt;br /&gt;&amp;nbsp; &amp;nbsp;2&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 70px;&quot;&gt;&amp;nbsp; &amp;nbsp;6&lt;br /&gt;4 2 3&lt;br /&gt;&amp;nbsp; &amp;nbsp;1&lt;br /&gt;&amp;nbsp; &amp;nbsp;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 방향이 전환되면 그 방향에 따라 주사위의 위치에 따른 값을 전부 변경해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1687935811506&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static int N, M, map[][], ju[];
    static int[][] dir = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}}; //동서북남
    static StringBuilder sb;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        N = Integer.parseInt(tokens.nextToken());
        M = Integer.parseInt(tokens.nextToken());
        map = new int[N][M];

        int x = Integer.parseInt(tokens.nextToken());
        int y = Integer.parseInt(tokens.nextToken());

        int K = Integer.parseInt(tokens.nextToken());

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; M; j++) {
                map[i][j] = Integer.parseInt(tokens.nextToken());
            }
        }

        //주사위 설정
        ju = new int[7];

        tokens = new StringTokenizer(br.readLine());
        sb = new StringBuilder();

        for (int i = 0; i &amp;lt; K; i++) {
            int[] now = roll(x, y, Integer.parseInt(tokens.nextToken()) - 1, sb);
            if(now == null) continue;
            x = now[0];
            y = now[1];
        }

        System.out.print(sb);

    }//end main

    private static int[] roll(int x, int y, int d, StringBuilder sb) {
        //방향대로 다음 위치 확인
        x += dir[d][0];
        y += dir[d][1];

        if (!isRange(x, y)) return null;

        changeJu(d);

        if(map[x][y] == 0){
            map[x][y] = ju[6];
        }else{
            ju[6] = map[x][y];
            map[x][y] = 0;
        }

        sb.append(ju[1]).append(&quot;\n&quot;); //가장 윗면의 값 출력

        return new int[]{x, y};

    }

    private static boolean isRange(int x, int y) {
        if (x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= M) return false;
        return true;
    }

    private static void changeJu(int d) {
        //굴리는 방향에 따라서 위치를 변경해줌. 1은 가장 윗면, 6은 가장 밑면이 됨
        //기본    1 2 3 4 5 6
        //오른    4 2 1 6 5 3
        //왼쪽    3 2 6 1 5 4
        //위쪽    5 1 3 4 6 2
        //남쪽    2 6 3 4 1 5

        int[] t = ju.clone();

        if (d == 0) { //동
            ju[1] = t[4];
            ju[3] = t[1];
            ju[4] = t[6];
            ju[6] = t[3];
        } else if (d == 1) { //서
            ju[1] = t[3];
            ju[3] = t[6];
            ju[4] = t[1];
            ju[6] = t[4];
        } else if (d == 2) { //북
            ju[1] = t[5];
            ju[2] = t[1];
            ju[5] = t[6];
            ju[6] = t[2];
        } else { //남
            ju[1] = t[2];
            ju[2] = t[6];
            ju[5] = t[1];
            ju[6] = t[5];
        }
    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>구현</category>
      <category>백준</category>
      <category>시뮬레이션</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/87</guid>
      <comments>https://nnindd.tistory.com/87#entry87comment</comments>
      <pubDate>Wed, 28 Jun 2023 16:10:45 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 3190 뱀</title>
      <link>https://nnindd.tistory.com/86</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/3190&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/3190&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뱀의 위치를 Queue에 담아서 관리한다. 꼬리가 줄어들어야 할 때, 머리가 늘어날 때 큐의 앞뒤로 삽입 삭제 연산을 해야 하기 때문에 ArrayDeque를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방향은 오른쪽으로 가는 방향에서 시작하여, 오른쪽으로 90도씩 방형을 전환하도록 방향 배열에 설정해두었고, 각 방향 전환이 일어날 때 1씩 더하고 빼는 연산에 모듈러 연산을 적용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while 문 안에서의 연산은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;머리를 늘린다.&lt;/li&gt;
&lt;li&gt;다음 위치가 벽인지, 자기 자신인지 확인한다.&lt;/li&gt;
&lt;li&gt;사과가 있는지 확인한다.&lt;/li&gt;
&lt;li&gt;사과가 없다면 꼬리 제거&lt;/li&gt;
&lt;li&gt;새로운 머리를 넣어준다.&lt;/li&gt;
&lt;li&gt;지금 초에 방향 전환이 있는지 확인한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 순서로 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1687852141986&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.StringTokenizer;

public class Main {
    static int N, map[][], time[];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;

        N = Integer.parseInt(br.readLine()); //맵 크기
        map = new int[N][N];
        time = new int[10001];

        int K = Integer.parseInt(br.readLine()); //사과의 개수
        int x, y;
        for (int i = 0; i &amp;lt; K; i++) {
            tokens = new StringTokenizer(br.readLine());
            x = Integer.parseInt(tokens.nextToken()) - 1;
            y = Integer.parseInt(tokens.nextToken()) - 1;
            map[x][y] = 1;
        }

        K = Integer.parseInt(br.readLine()); //방향 정보
        char w;
        for (int i = 0; i &amp;lt; K; i++) {
            tokens = new StringTokenizer(br.readLine());
            x = Integer.parseInt(tokens.nextToken());
            w = tokens.nextToken().charAt(0);

            time[x] = w == 'D' ? 1 : -1; //왼쪽 -1, 오른쪽 1 저장
        }

        System.out.println(play());

    }

    private static int play() {
        int res = 0; //게임 진행 시간
        int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; //오른쪽으로 시계방향
        int d = 0; //오른쪽
        ArrayDeque&amp;lt;int[]&amp;gt; pos = new ArrayDeque&amp;lt;&amp;gt;(); //뱀의 모든 위치 저장
        pos.offer(new int[]{0, 0}); //머리
        //자기 자신 표시
        map[0][0] = 999;

        int nx, ny;
        while (true) {
            res++;

            int[] cur = pos.peek();

            //1. 머리 늘리기
            nx = cur[0] + dir[d][0];
            ny = cur[1] + dir[d][1];

            //2. 벽인지, 자기자신인지 확인
            if (!isRange(nx, ny) || map[nx][ny] == 999) break;

            //3. 사과 유무 확인

            if (map[nx][ny] == 0) { //사과를 안먹는 경우
                int[] tail = pos.pollLast();
                map[tail[0]][tail[1]] = 0;
            }
            map[nx][ny] = 999;
            pos.offerFirst(new int[]{nx, ny});
            
            //4. 초마다 방향 전환이 있는지 확인 후 방향을 바꿔줌
            if (time[res] == -1) {
                d = (d + 3) % 4; //빼기로 진행하면 마이너스값이 나오기 때문에 3을 더해서 모듈러 연산
            } else if (time[res] == 1) {
                d = (d + 1) % 4;
            }
        }

        return res;
    }

    private static boolean isRange(int x, int y) {
        if (x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= N) return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>구현</category>
      <category>백준</category>
      <category>시뮬레이션</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/86</guid>
      <comments>https://nnindd.tistory.com/86#entry86comment</comments>
      <pubDate>Tue, 27 Jun 2023 16:53:29 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 14940 쉬운 최단거리</title>
      <link>https://nnindd.tistory.com/85</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14940&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14940&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bfs로 풀었다. 2인 지점에서 시작하고 이동할때마다 가중치를 증가시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열은 입력받은 배열 map과 결과를 저장할 배열 res 두개를 사용한다. map에서 1로 갈 수 있는데, res에서 배열 초기값인 0이라면 도달하지 못했기 때문에 -1로 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1687510151777&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static int N, M, map[][], res[][];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        N = Integer.parseInt(tokens.nextToken());
        M = Integer.parseInt(tokens.nextToken());

        map = new int[N][M];
        res = new int[N][M];

        Queue&amp;lt;int[]&amp;gt; q = new ArrayDeque&amp;lt;&amp;gt;();
        boolean[][] v = new boolean[N][M];

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; M; j++) {
                map[i][j] = Integer.parseInt(tokens.nextToken());
                if (map[i][j] == 2) {
                    q.offer(new int[]{i, j, 0});
                    v[i][j] = true;
                    map[i][j] = 0;
                }
            }
        }

        bfs(q, v);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &amp;lt; N; i++) {
            for (int j = 0; j &amp;lt; M; j++) {
                //map은 1인데 res에 0으로 되어있으면 도달하지 못함
                if (map[i][j] == 1 &amp;amp;&amp;amp; res[i][j] == 0) {
                    sb.append(-1);
                } else {
                    sb.append(res[i][j]);
                }
                sb.append(&quot; &quot;);
            }
            sb.append(&quot;\n&quot;);
        }
        System.out.print(sb);

    }

    private static void bfs(Queue&amp;lt;int[]&amp;gt; q, boolean[][] v) {
        int[][] dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

        while (!q.isEmpty()) {
            int[] cur = q.poll();

            for (int d = 0; d &amp;lt; 4; d++) {
                int nx = cur[0] + dir[d][0];
                int ny = cur[1] + dir[d][1];

                if (!isRange(nx, ny) || v[nx][ny] || map[nx][ny] == 0) continue;

                res[nx][ny] = cur[2] + 1;
                v[nx][ny] = true;
                q.offer(new int[]{nx, ny, cur[2] + 1});
            }
        }
    }

    private static boolean isRange(int x, int y) {
        if (x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= M) return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>BFS</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/85</guid>
      <comments>https://nnindd.tistory.com/85#entry85comment</comments>
      <pubDate>Fri, 23 Jun 2023 17:52:34 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 9461 파도반 수열</title>
      <link>https://nnindd.tistory.com/84</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/9461&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/9461&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수열의 규칙을 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1 1 1 2 2 3 4 5 6 7 9 12를 봤을 때, 1 1 1 2 2 까지는 규칙을 찾기 어렵지만, 3부터는 n-1과 n-5의 값이 합쳐진게 답이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제&lt;span style=&quot;color: #333333;&quot;&gt;에서 &lt;span style=&quot;text-align: start;&quot;&gt;&lt;code&gt;P(1)부터 P(10)까지 첫 10개 숫자는 1, 1, 1, 2, 2, 3, 4, 5, 7, 9이다.&lt;/code&gt; 라고 되어있기 때문에 각 단계별로 배열을 만든 다음 값을 사용한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;N이 100까지 들어오기 때문에 배열의 크기를 100으로 잡고, 값이 int 자료형의 범위를 벗어나기 때문에 long을 사용한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1687507876565&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        //int 자료형을 사용하면 오버플로우 발생
        long[] dp = new long[101];
        dp[1] = 1;
        dp[2] = 1;
        dp[3] = 1;
        dp[4] = 2;
        dp[5] = 2;
        //이후 값은 dp[n-1] + dp[n-5] 값을 따름
        for (int i = 6; i &amp;lt; dp.length; i++) {
            dp[i] = dp[i-1] + dp[i-5];
        }

        int T = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();

        while(T-- &amp;gt; 0){
            int N = Integer.parseInt(br.readLine());
            sb.append(dp[N]).append(&quot;\n&quot;);
        }
        System.out.println(sb);
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>다이나믹프로그래밍</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/84</guid>
      <comments>https://nnindd.tistory.com/84#entry84comment</comments>
      <pubDate>Fri, 23 Jun 2023 17:12:13 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 11724 연결 요소의 개수</title>
      <link>https://nnindd.tistory.com/83</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11724&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11724&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니온 파인드를 사용했다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;find : 배열의 값(부모)이 들어온 숫자와 같다면 그 값을 돌려준다. 다르다면 부모의 값을 계속 타고 올라가며 찾는다.&lt;/li&gt;
&lt;li&gt;union : find를 사용하여 각 부모를 찾는다. 두 값의 부모가 같다면 false를 돌려준다. 값이 다를 경우 작은 쪽을 부모로 만들어주고 true를 돌려준다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막에 N만큼 순회하며 부모의 값을 집합에 넣어주고, 집합의 크기를 출력한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1687506270568&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

public class Main {
    static int N, parent[];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        N = Integer.parseInt(tokens.nextToken());
        int M = Integer.parseInt(tokens.nextToken());

        parent = new int[N];

        initArr();

        for (int i = 0; i &amp;lt; M; i++) {
            tokens = new StringTokenizer(br.readLine());
            union(Integer.parseInt(tokens.nextToken()) - 1, Integer.parseInt(tokens.nextToken()) - 1);
        }

        Set&amp;lt;Integer&amp;gt; set = new HashSet&amp;lt;&amp;gt;();
        for (int i = 0; i &amp;lt; N; i++) {
            set.add(find(i));
        }
        System.out.println(set.size());
    }

    private static void initArr() {
        for (int i = 0; i &amp;lt; N; i++) {
            parent[i] = i;
        }
    }

    private static int find(int a) {
        if (parent[a] == a) return a;
        return find(parent[a]);
    }

    private static boolean union(int a, int b) {
        a = find(a);
        b = find(b);

        if (a == b) return false;

        if (a &amp;lt;= b) parent[b] = a;
        else parent[a] = b;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>백준</category>
      <category>유니온파인드</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/83</guid>
      <comments>https://nnindd.tistory.com/83#entry83comment</comments>
      <pubDate>Fri, 23 Jun 2023 16:44:47 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 11403 경로 찾기</title>
      <link>https://nnindd.tistory.com/82</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11403&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11403&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2가지 방법으로 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;dfs&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한 행에 대해서 방문 배열 초기화&lt;/li&gt;
&lt;li&gt;지금 행과 열이 1이라면 연속되는 곳을 찾기 위해 dfs 호출&lt;/li&gt;
&lt;li&gt;dfs 내에서 방문 처리, j에 대해서 연결된 다른 노드를 찾고 시작점과 이어주기 위해 dfs 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;플로이드 워셜&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;i와 k가 연결되고, k와 j가 연결된 경우 i와 j를 연결시켜줌&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 플로이드 워셜이 생각 나지 않아 bfs, dfs 여러 방법으로 풀어봤었는데, 가중치가 없더라도 모든 간선을 확인하고, 연속해서 확인해야 하는 경우 플로이드 워셜을 사용하니 훨씬 더 간단하게 풀렸다. 또한 input이 100까지 들어오기 때문에 100^3번 수행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnCWoG/btskVLQlroK/ehUgGbWbvVx3AMqOxo2IwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnCWoG/btskVLQlroK/ehUgGbWbvVx3AMqOxo2IwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnCWoG/btskVLQlroK/ehUgGbWbvVx3AMqOxo2IwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnCWoG%2FbtskVLQlroK%2FehUgGbWbvVx3AMqOxo2IwK%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;200&quot; height=&quot;216&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 dfs, 위에는 플로이드 워셜로 풀었는데 둘 다 100^3을 수행해서 메모리와 시간상 별 차이는 없다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드 1 - dfs&lt;/h4&gt;
&lt;pre id=&quot;code_1687419576117&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static int N, map[][], res[][];
    static boolean[] v;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;

        N = Integer.parseInt(br.readLine());
        map = new int[N][N];
        res = new int[N][N];

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; N; j++) {
                map[i][j] = Integer.parseInt(tokens.nextToken());
            }
        }//end input

        for (int i = 0; i &amp;lt; N; i++) {
            v = new boolean[N];

            for (int j = 0; j &amp;lt; N; j++) {
                if(map[i][j] == 1 &amp;amp;&amp;amp; !v[j]){
                    dfs(i, j);
                }
            }
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &amp;lt; N; i++) {
            for (int j = 0; j &amp;lt; N; j++) {
                sb.append(res[i][j]).append(&quot; &quot;);
            }
            sb.append(&quot;\n&quot;);
        }
        System.out.println(sb);

    }

    private static void dfs(int x, int y) {
        //x, y가 1인 상태
        //y에 연결된 다른 간선 찾아야 함
        v[y] = true;
        res[x][y] = 1;

        for (int i = 0; i &amp;lt; N; i++) {
            if(map[y][i] == 1 &amp;amp;&amp;amp; !v[i]){
                //y와 연결된 간선을 시작한 노드와 이어
                dfs(x, i);
            }
        }
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드 2 - 플로이드 워셜&lt;/h4&gt;
&lt;pre id=&quot;code_1687419876354&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;

        int N = Integer.parseInt(br.readLine());
        int[][] map = new int[N][N];

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; N; j++) {
                map[i][j] = Integer.parseInt(tokens.nextToken());
            }
        }//end input

        for (int k = 0; k &amp;lt; N; k++) {
            for (int i = 0; i &amp;lt; N; i++) {
                for (int j = 0; j &amp;lt; N; j++) {
                    if (map[i][k] == 1 &amp;amp;&amp;amp; map[k][j] == 1) {
                        map[i][j] = 1;
                    }
                }
            }
        }


        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &amp;lt; N; i++) {
            for (int j = 0; j &amp;lt; N; j++) {
                sb.append(map[i][j]).append(&quot; &quot;);
            }
            sb.append(&quot;\n&quot;);
        }
        System.out.print(sb);

    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>DFS</category>
      <category>그래프</category>
      <category>백준</category>
      <category>플로이드워셜</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/82</guid>
      <comments>https://nnindd.tistory.com/82#entry82comment</comments>
      <pubDate>Thu, 22 Jun 2023 16:49:28 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 16928 뱀과 사다리 게임</title>
      <link>https://nnindd.tistory.com/81</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/16928&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/16928&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;bfs로 주사위 6개에 대해서 탐색&lt;/li&gt;
&lt;li&gt;시작 위치는 1&lt;/li&gt;
&lt;li&gt;배열에 맵의 정보 설정&lt;/li&gt;
&lt;li&gt;100이 넘지 않는 경우 맵을 이동하는지 확인 후 갱신해주기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 bfs에서 이 조건을 지켜서 풀었다. 처음에는 시작 위치를 0으로 잡았는데, 문제 조건에서 1에서 시작한다고 되어있기 때문에 1로 해야 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1687413157534&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(tokens.nextToken());
        int M = Integer.parseInt(tokens.nextToken());

        int[] map = new int[101];

        int a, b;
        for (int i = 0; i &amp;lt; N + M; i++) {
            tokens = new StringTokenizer(br.readLine());
            a = Integer.parseInt(tokens.nextToken());
            b = Integer.parseInt(tokens.nextToken());

            map[a] = b;
        }

        System.out.println(bfs(map));
    }

    private static int bfs(int[] map) {
        int res = 0;
        Queue&amp;lt;int[]&amp;gt; q = new ArrayDeque&amp;lt;&amp;gt;();
        boolean[] v = new boolean[101];

        q.offer(new int[]{1, 0}); //위치와 횟수
        v[1] = true;

        while (!q.isEmpty()) {
            int[] cur = q.poll();

            //1~6 주사위를 굴림
            for (int d = 1; d &amp;lt;= 6; d++) {
                int next = cur[0] + d;

                if (v[next] || next &amp;gt; 100) continue;

                //도착
                if (next == 100) {
                    res = cur[1] + 1;
                    return res;
                }

                //맵 방향 설정
                if (map[next] != 0) {
                    next = map[next];
                }
                //다음 위치
                v[next] = true;
                q.offer(new int[]{next, cur[1] + 1});

            }
        }

        return res;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>BFS</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/81</guid>
      <comments>https://nnindd.tistory.com/81#entry81comment</comments>
      <pubDate>Thu, 22 Jun 2023 15:07:32 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 9019 DSLR</title>
      <link>https://nnindd.tistory.com/80</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/9019&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/9019&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bfs 문제인데 L, R 연산 계산하는 법에서 시간이 많이 걸렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Queue에 저장할 class를 선언해주고, 이 안에 D,S,L,R 연산을 추가했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 각 연산에서 값이 달라졌어도 cur 값이 유지가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1686834392256&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());

        while (T-- &amp;gt; 0) {
            tokens = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(tokens.nextToken());
            int b = Integer.parseInt(tokens.nextToken());

            sb.append(bfs(a, b)).append(&quot;\n&quot;);
        }
        System.out.println(sb);
    }

    static class Pos {
        int num;
        String order;

        public Pos(int num, String order) {
            this.num = num;
            this.order = order;
        }

        public int D() {
            return (num * 2) % 10000;
        }

        public int S() {
            return num == 0 ? 9999 : num - 1;
        }

        public int L() {
            //1234 -&amp;gt; 2341
            //123 -&amp;gt; 231
            //12 -&amp;gt; 21
            return (num % 1000) * 10 + (num / 1000);
        }

        public int R() {
            //1234 -&amp;gt; 4123
            return (num % 10) * 1000 + (num / 10);
        }

    }

    private static String bfs(int a, int b) {
        //D, S, L, R의 연산을 수행함
        Queue&amp;lt;Pos&amp;gt; q = new ArrayDeque&amp;lt;&amp;gt;();
        q.offer(new Pos(a, &quot;&quot;));
        boolean[] v = new boolean[10000];
        v[a] = true;

        String res = &quot;&quot;;

        while (!q.isEmpty()) {
            Pos cur = q.poll();

            if (cur.num == b) {
                res = cur.order;
                break;
            }

            for (int i = 0; i &amp;lt; 4; i++) {
                Pos next;
                if (i == 0) {
                    next = new Pos(cur.D(), cur.order+&quot;D&quot;);
                } else if (i == 2) {
                    next = new Pos(cur.S(), cur.order+&quot;S&quot;);
                } else if (i == 3) {
                    next = new Pos(cur.L(), cur.order+&quot;L&quot;);
                } else {
                    next = new Pos(cur.R(), cur.order+&quot;R&quot;);
                }

                if (v[next.num]) continue;
                v[next.num] = true;
                q.offer(next);
            }

        }
        return res;
    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>BFS</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/80</guid>
      <comments>https://nnindd.tistory.com/80#entry80comment</comments>
      <pubDate>Thu, 15 Jun 2023 22:08:42 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 17219 비밀번호 찾기</title>
      <link>https://nnindd.tistory.com/79</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17219&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/17219&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맵에 &amp;lt;사이트, 비밀번호&amp;gt;로 저장하고 찾으면 된다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시나 더 빠르게 푸는 방법이 있나 싶어 백준에 정답 기록을 봤는데 비슷하게 푼 것 같다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1686827398122&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(tokens.nextToken());
        int M = Integer.parseInt(tokens.nextToken());

        HashMap&amp;lt;String, String&amp;gt; map = new HashMap&amp;lt;&amp;gt;();

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            map.put(tokens.nextToken(), tokens.nextToken());
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &amp;lt; M; i++) {
            sb.append(map.get(br.readLine())).append(&quot;\n&quot;);
        }
        System.out.print(sb);
    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/79</guid>
      <comments>https://nnindd.tistory.com/79#entry79comment</comments>
      <pubDate>Thu, 15 Jun 2023 20:11:53 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 20529 가장 가까운 세 사람의 심리적 거리</title>
      <link>https://nnindd.tistory.com/78</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/20529&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/20529&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 조합으로 3개를 선택해서 풀었는데 N이 100,000까지 들어오기 때문에 시간 초과가 난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심리적 거리가 0이 될 경우는 모두 같은 mbti인 경우이고, N이 32를 넘는 경우 무조건 심리적 거리가 0이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜냐하면 N이 32인 경우 서로 다른 mbti가 입력으로 들어왔을 경우 최소 2개씩 중복되는 mbti가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 N이 33이라면 2개로 중복된 mbti가 3개가 되기 때문에 이 때 심리적 거리는 0이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 입력을 받고 N이 32를 넘는 경우에는 검사를 하지 않고 결과를 0으로 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N이 32를 넘지 않는 경우에는 조합으로 3개를 선택해서 심리적 거리를 계산한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1686662352516&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static int res;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());

        while (T-- &amp;gt; 0) {
            int N = Integer.parseInt(br.readLine());
            tokens = new StringTokenizer(br.readLine());

            //32개가 넘으면 무조건 0이 됨. 이미 같은 유형이 2개씩 존재하기 때문
            if (N &amp;gt; 32) {
                sb.append(0).append(&quot;\n&quot;);
                continue;
            }

            String[] type = new String[N];
            for (int i = 0; i &amp;lt; N; i++) {
                type[i] = tokens.nextToken();
            }

            //조합으로 선택
            res = Integer.MAX_VALUE;
            comb(0, 0, new String[3], type, N);
            sb.append(res).append(&quot;\n&quot;);

        }
        System.out.print(sb);
    }

    private static void comb(int cnt, int start, String[] s, String[] type, int N) {
        if (cnt == 3) {
            int temp = 0;
            for (int i = 0; i &amp;lt; 4; i++) {
                if (s[0].charAt(i) != s[1].charAt(i)) temp++;
                if (s[0].charAt(i) != s[2].charAt(i)) temp++;
                if (s[1].charAt(i) != s[2].charAt(i)) temp++;
            }
            res = Math.min(res, temp);
            return;
        }

        for (int i = start; i &amp;lt; N; i++) {
            s[cnt] = type[i];
            comb(cnt+1, i+1, s, type, N);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/78</guid>
      <comments>https://nnindd.tistory.com/78#entry78comment</comments>
      <pubDate>Tue, 13 Jun 2023 22:23:35 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 14890 경사로</title>
      <link>https://nnindd.tistory.com/77</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14890&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14890&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SW Expert Academy에서 풀었던 문제이다. 활주로 건설과 같은 문제인데 그때에는 행과 열에 대해서 모두 조사하는 방식이었지만, 이번에는 맵 2개를 선언하여 하나의 맵은 90도 회전한 맵으로 저장하고 두 맵을 한 행씩 조사하는 로직으로 변경했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;이전 값과 다를 때 차이가 1이 아니라면 이 행은 경사로를 세울 수 없어 false를 리턴한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전값과의 차이가 1이라면 높이가 올라가는 경우, 아니라면 낮아지는 경우에 따라 경사로를 세울 수 있는 조건 확인을 다르게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;높아지는 경우, L만큼 공간을 만들 수 있는지 확인하고 만들 수 없다면 false, 만들 수 있다면 cnt와 prev 값을 갱신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;낮아지는 경우, 지금 위치에서 L만큼 위치까지 전부 같은 값인지 확인한다. 다른 값이 있다면 false, 전부 같은 값이라면 경사로를 만들 수 있고, L만큼 만든 다음 위치로 인덱스와 cnt를 조절한다. 이때 이 곳은 경사로를 만들었기 때문에 cnt는 0으로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1686401148123&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static int N, L, res, map[][], map2[][];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        N = Integer.parseInt(tokens.nextToken());
        L = Integer.parseInt(tokens.nextToken());
        map = new int[N][N];
        map2 = new int[N][N]; //i,j위치 반전시킨 맵

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; N; j++) {
                map[i][j] = Integer.parseInt(tokens.nextToken());
                map2[j][i] = map[i][j];
            }
        }

        res = 0;

        //기본 맵 행 검사, 회전한 맵 행 검사
        for (int i = 0; i &amp;lt; N; i++) {
            if (checkRow(map[i])) {
                res++;
            }
            if(checkRow(map2[i])){
                res++;
            }
        }

        System.out.println(res);
    }

    private static boolean checkRow(int[] rows) {
        //높이가 달라졌을 때 경사로를 생성할 수 있는지 확인
        int prev = rows[0];
        int cnt = 1;
        for (int i = 1; i &amp;lt; N; i++) {
            if (prev == rows[i]) { //높이가 같은 경우 그냥 증가
                cnt++;
                continue;
            }
            //높이가 다를 때
            if (Math.abs(prev - rows[i]) != 1) {
                //높이 차이가 1이 아니라면 경사로 만들지 못함
                return false;
            }
            //높이 차이가 1일 때
            //높아지는 경우 -&amp;gt; L만큼 공간을 만들 수 있는지 확인
            if (rows[i] - prev == 1) {
                if (cnt &amp;gt;= L) {
                    //경사로 생성
                    cnt = 1;
                    prev = rows[i];
                } else {
                    return false;
                }
            } else {
                //낮아지는 경우
                boolean flag = true;
                for (int j = i + 1; j &amp;lt; i + L; j++) {
                    if (!(j &amp;lt; N &amp;amp;&amp;amp; rows[j] == rows[i])) {
                        flag = false;
                        break;
                    }
                }
                if (!flag) {
                    return false;
                } else {
                    //만들 수 있는 경우 만들고 경사로 만든 인덱스 조정하기
                    cnt = 0;
                    i = i + L - 1;
                    prev = rows[i];
                }

            }

        }
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>구현</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/77</guid>
      <comments>https://nnindd.tistory.com/77#entry77comment</comments>
      <pubDate>Sat, 10 Jun 2023 21:53:07 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 14503 로봇 청소기</title>
      <link>https://nnindd.tistory.com/76</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14503&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14503&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;청소기가 더 이상 움직일 수 없는 조건은 주변 칸이 전부 청소된 상태이고, 후진할 수 없는 경우이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while문을 실행하여 더 이상 움직일 수 없는 경우에 대해서 -1 값으로 처리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;move 함수는 로봇 청소기가 r, c, d값에 따라 한번 움직이는 함수이다. return값는 각 상황에 따른 새롭게 이동해야 하는 위치와 좌표가 반환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;move 함수에서 문제의 조건대로 함수를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개선할 점은 청소할 영역이 한가지만 남았는데, 로봇청소기가 해당 방향을 발견할때까지 뱅뱅 도는 경우이다&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 8.02326%; height: 65px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;span&gt;1 0 1&lt;/span&gt;&lt;br /&gt;&lt;span&gt;1 * 1&lt;/span&gt;&lt;br /&gt;1 1 1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로봇 청소기가 *에 있을 때 0인 곳으로만 이동할 수 있는데 저 방향을 발견할때까지 계속 도는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어차피 청소하는 칸의 개수만 구하는 것이기 때문에 move 함수를 계속 실행시키는 것이 아니라 한 방향으로만 가야한다면 해당 방향을 바로 갈 수 있도록 return 값을 수정하는 것이 더 효율적인 코드라고 생각된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1686319931218&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main_14503_로봇청소기 {

    static int N, M, res, map[][];
    static int[][] dir = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; //북 동 남 서

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        N = Integer.parseInt(tokens.nextToken());
        M = Integer.parseInt(tokens.nextToken());
        map = new int[N][M];

        tokens = new StringTokenizer(br.readLine());
        //처음 위치와 방향
        int r = Integer.parseInt(tokens.nextToken());
        int c = Integer.parseInt(tokens.nextToken());
        int d = Integer.parseInt(tokens.nextToken());

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; M; j++) {
                //0 청소되지 않은 칸, 1 벽
                map[i][j] = Integer.parseInt(tokens.nextToken());
            }
        }

        res = 0;

        while (r != -1 &amp;amp;&amp;amp; c != -1 &amp;amp;&amp;amp; d != -1) {
            int[] temp = move(r, c, d);
            r = temp[0];
            c = temp[1];
            d = temp[2];
        }

        System.out.println(res);
    }

    private static int[] move(int r, int c, int d) {
        //현재 칸 확인
        if (checkNowArea(r, c)) {
            //청소되지 않았다면 청소
            res++;
            map[r][c] = -1; //청소되었다고 표시
        }

        //주변 4칸 확인
        if (checkAroundArea(r, c)) {//다 청소된 경우
            //후진 가능한지 확인
            int[] temp = isBack(r, c, d);

            //후진 가능하다면 후진, 후진 불가능이면 작동 멈춤
            if (r == temp[0] &amp;amp;&amp;amp; c == temp[1] &amp;amp;&amp;amp; d == temp[2]) {
                //후진 불가능한 경우 멈춤
                return new int[]{-1, -1, -1};
            }
            //후진 가능한 경우
            return new int[]{temp[0], temp[1], temp[2]};

        } else {//청소되지 않은 칸이 있는 경우
            //방향 반시계로 90도 회전 -&amp;gt; 3 더하고 모듈러
            d = (d + 3) % 4;

            //앞쪽 칸이 청소되지 않은 빈칸이면 전진하고 다시 움직임
            int nx = r + dir[d][0];
            int ny = c + dir[d][1];
            if (isRange(nx, ny) &amp;amp;&amp;amp; map[nx][ny] == 0) {//청소되지 않은 칸인 경우
                return new int[]{nx, ny, d}; //한칸 전진
            }
            //그냥 방향만 바꾸고 제자리
            return new int[]{r, c, d};

        }
    }

    private static int[] isBack(int r, int c, int d) {
        //현재 위치에서 후진 할 수 있는지 확인
        //현재 방향의 반대 방향 선택. 2를 더하고 모듈러
        int nd = (d + 2) % 4;
        int nx = r + dir[nd][0];
        int ny = c + dir[nd][1];

        //뒤로 갈 수 있고, 벽이 아닌 경우
        if (isRange(nx, ny) &amp;amp;&amp;amp; map[nx][ny] != 1) return new int[]{nx, ny, d};
        return new int[]{r, c, d};

    }

    private static boolean checkAroundArea(int r, int c) {
        //주변에 0이 없다면 true
        for (int d = 0; d &amp;lt; 4; d++) {
            int nx = r + dir[d][0];
            int ny = c + dir[d][1];

            if (isRange(nx, ny) &amp;amp;&amp;amp; map[nx][ny] == 0)
                return false;
        }
        return true;
    }

    private static boolean isRange(int x, int y) {
        if (x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= M) return false;
        return true;
    }

    private static boolean checkNowArea(int r, int c) {
        if (map[r][c] == 0) return true; //청소되지 않은 칸이라면 true
        return false;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>구현</category>
      <category>백준</category>
      <category>시뮬레이션</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/76</guid>
      <comments>https://nnindd.tistory.com/76#entry76comment</comments>
      <pubDate>Fri, 9 Jun 2023 23:17:26 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 13458 시험 감독</title>
      <link>https://nnindd.tistory.com/75</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/13458&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/13458&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감독관의 수가 int 자료형 범위를 벗어나기 때문에 long으로 선언&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총감독관은 한 시험장마다 한명이기 때문에 &lt;code&gt;응시자 수 - 감독가능수&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부감독관은 남은 &lt;code&gt;응시자 수 - 감독가능수&lt;/code&gt;를 했을 때 나머지가 0이라면 응시자수 / 감독가능수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지가 0이 아니라면 &lt;code&gt;응시자 수 - 감독가능수 + 1&lt;/code&gt;을 &lt;code&gt;감독관 수&lt;/code&gt;에 더해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1685626510007&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine()); //시험장의 개수

        int[] map = new int[N];
        StringTokenizer tokens = new StringTokenizer(br.readLine());
        for (int i = 0; i &amp;lt; N; i++) { //응시자의 수
            map[i] = Integer.parseInt(tokens.nextToken());
        }

        tokens = new StringTokenizer(br.readLine());
        int B = Integer.parseInt(tokens.nextToken()); //총감독관
        int C = Integer.parseInt(tokens.nextToken()); //부감독관

        //총 감독관은 시험장 당 1명
        //부 감독관은 여러명 가능
        //감독관 최소

        long cnt = 0;
        for (int i = 0; i &amp;lt; N; i++) {
            //총감독관
            if (map[i] &amp;lt; B) {//총감독관이 모두 감독 가능
                cnt++;
                continue;
            }
            map[i] -= B;
            cnt++;

            //부감독관
            if (map[i] &amp;lt;= 0) continue;

            int a = map[i] / C;
            int b = map[i] % C;
            if (b != 0) {
                cnt += a + 1;
            } else {
                cnt += a;
            }
        }
        System.out.println(cnt);

    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/75</guid>
      <comments>https://nnindd.tistory.com/75#entry75comment</comments>
      <pubDate>Thu, 1 Jun 2023 22:37:15 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 1316 그룹 단어 체커</title>
      <link>https://nnindd.tistory.com/74</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1316&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1316&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과값이 될 그룹 단어의 개수를 N으로 초기화 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 받은 단어의 글자수만큼 반복문을 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반복문 안에서 단어를 한글자씩 읽고, map을 활용한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) getOrDefault를 사용하여 존재하는 경우 값을 가져오고, 없는 경우 -1로 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) -1인 경우에는 현재 단어가 몇번째 단어인지 인덱스를 같이 넣어준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 값이 존재하는데, 그 값이 현재 단어의 인덱스와 1 차이가 아니라면 그룹 단어가 되지 못하기 때문에 그룹 단어의 수를 감소하고 다음 입력으로 넘어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 ab&lt;b&gt;a &lt;/b&gt;를 읽었는데 map에서 'a'의 값은 0이다. 현재 인덱스는 2이기 때문에 둘의 차이가 1이 아니다. 따라서 그룹 단어가 되지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) 값이 존재하고, 인덱스 차이가 1이라면 현재 인덱스로 map의 값을 갱신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1685022492792&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());

        int res = N;
        for (int i = 0; i &amp;lt; N; i++) {
            HashMap&amp;lt;Character, Integer&amp;gt; map = new HashMap&amp;lt;&amp;gt;();
            String str = br.readLine();
            for (int j = 0; j &amp;lt; str.length(); j++) {
                char w = str.charAt(j);
                int val = map.getOrDefault(w, -1);
                if(val == -1){ //존재하지 않는 경우
                    map.put(w, j);
                    continue;
                }
                //값이 존재하는 경우 인덱스 비교
                if(j-1 != val){
                    //연속으로 존재하지 않는다 그룹단어가 아님
                    res--;
                    break;
                }
                //값이 존재하고 인덱스가 1개 차이 날 때
                map.replace(w, j);
            }
        }
        System.out.println(res);
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>문자열</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/74</guid>
      <comments>https://nnindd.tistory.com/74#entry74comment</comments>
      <pubDate>Thu, 25 May 2023 22:53:20 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers MySQL] 조건에 맞는 도서와 저자 리스트 출력하기</title>
      <link>https://nnindd.tistory.com/73</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/144854&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/144854&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작가 아이디가 일치하고 경제인 행에 대해서만 조회&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1684571656550&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select BOOK_ID, AUTHOR_NAME, date_format(PUBLISHED_DATE,&quot;%Y-%m-%d&quot;) as PUBLISHED_DATE
from BOOK as b, AUTHOR as a
where CATEGORY = &quot;경제&quot; and b.AUTHOR_ID = a.AUTHOR_ID
order by PUBLISHED_DATE;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/73</guid>
      <comments>https://nnindd.tistory.com/73#entry73comment</comments>
      <pubDate>Sat, 20 May 2023 17:34:59 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers MySQL] 성분으로 구분한 아이스크림 총 주문량</title>
      <link>https://nnindd.tistory.com/72</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/133026&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/133026&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조인 실행 후 그룹함수를 적용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 문제 조건에 &lt;code&gt;총주문량이 작은 순서대로 조회하는 SQL 문&lt;/code&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1684570976552&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select INGREDIENT_TYPE, SUM(TOTAL_ORDER) as TOTAL_ORDER
from FIRST_HALF as f join ICECREAM_INFO as i
on f.FLAVOR = i.FLAVOR
group by INGREDIENT_TYPE
order by TOTAL_ORDER;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/72</guid>
      <comments>https://nnindd.tistory.com/72#entry72comment</comments>
      <pubDate>Sat, 20 May 2023 17:28:53 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers MySQL] 가격대 별 상품 개수 구하기</title>
      <link>https://nnindd.tistory.com/71</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131530&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/131530&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그룹화 하여 그룹화 한 대상과 개수를 표시한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TRUNCATE(대상, 자리수)는 대상을 자리수만큼 보일 수 있게 내림을 한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 45.9302%; height: 51px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;TRUNCATE(12.345, 2)&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;12.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;TRUNCATE(12.345, 0)&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;TRUNCATE(12.345, -2)&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이너스가 붙으면 0이 1의 자리가 되어 12가 나타나고, -2인 경우 3의 자리가 없이 때문에 0이 된다. -1을 하면 10이 나오게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;truncate를 PRICE_GROUP라고 지정했기 때문에 이것을 기준으로 그룹 함수를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1684570255699&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select truncate(price, -4) as PRICE_GROUP, count(product_id) as PRODUCTS
from product
group by PRICE_GROUP
order by PRICE_GROUP;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/71</guid>
      <comments>https://nnindd.tistory.com/71#entry71comment</comments>
      <pubDate>Sat, 20 May 2023 17:16:37 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers MySQL] 가격이 제일 비싼 식품의 정보 출력하기</title>
      <link>https://nnindd.tistory.com/70</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131115&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/131115&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;집계 함수 max를 사용하면 하나의 행만 리턴하기 때문에 최대 가격을 서브 쿼리로 가져오고 해당하는 가격의 상품 정보를 select 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1684569248237&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select product_id, product_name, product_cd, category, price
from food_product
where price = (
    select max(price)
    from food_product
);&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/70</guid>
      <comments>https://nnindd.tistory.com/70#entry70comment</comments>
      <pubDate>Sat, 20 May 2023 16:54:30 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers MySQL] 가장 비싼 상품 구하기</title>
      <link>https://nnindd.tistory.com/69</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131697&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/131697&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1684568704835&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select MAX(price) as MAX_PRICE
from product&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/69</guid>
      <comments>https://nnindd.tistory.com/69#entry69comment</comments>
      <pubDate>Sat, 20 May 2023 16:45:28 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers MySQL] 조건에 부합하는 중고거래 댓글 조회하기</title>
      <link>https://nnindd.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;문제 링크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/164673&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/164673&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;두번째 방법 : 테이블 2개 두고 where로 조건 걸기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 것이 더 효율적인 방법인지 생각해보고 싶다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조인의 경우는 where절에서 필터링을 걸기 때문에 조인을 수행하고 난 뒤면 데이터의 크기가 너무 커지지 않는지 궁금하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 두번째 방법을 쓰는 경우 where에서 board_id가 같은 것만 선택하는 것 깜빡하지 않기!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드&lt;/p&gt;
&lt;pre id=&quot;code_1684564787122&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 조인
select
    TITLE, 
    b.BOARD_ID, 
    REPLY_ID, 
    r.WRITER_ID, 
    r.CONTENTS, 
    DATE_FORMAT(r.CREATED_DATE, &quot;%Y-%m-%d&quot;) as CREATED_DATE
from USED_GOODS_BOARD as b join USED_GOODS_REPLY as r
on b.BOARD_ID = r.BOARD_ID
where YEAR(b.CREATED_DATE) = 2022 and MONTH(b.CREATED_DATE) = 10
order by r.CREATED_DATE, TITLE;

# where
select 
    title, 
    b.board_id, 
    reply_id, 
    r.writer_id, 
    r.contents, 
    date_format(r.created_date, &quot;%Y-%m-%d&quot;) as CREATED_DATE
from used_goods_board as b, used_goods_reply as r
where b.board_id = r.board_id
and date_format(b.created_date, &quot;%Y-%m&quot;) = '2022-10'
order by r.created_date, title;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/68</guid>
      <comments>https://nnindd.tistory.com/68#entry68comment</comments>
      <pubDate>Sat, 20 May 2023 15:46:20 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers MySQL] 과일로 만든 아이스크림 고르기</title>
      <link>https://nnindd.tistory.com/67</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/133025&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/133025&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두가지 방법으로 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째는 서브쿼리를 사용하였고, 두번째는 join을 사용했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1684563403783&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 서브쿼리
select flavor
from first_half
where total_order &amp;gt; 3000 and flavor in (
    select flavor
    from icecream_info
    where ingredient_type = 'fruit_based'
)
order by total_order desc;

# 조인
select first_half.flavor
from first_half join icecream_info
on first_half.flavor = icecream_info.flavor
where total_order &amp;gt; 3000 and ingredient_type = 'fruit_based'
order by total_order desc;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/67</guid>
      <comments>https://nnindd.tistory.com/67#entry67comment</comments>
      <pubDate>Sat, 20 May 2023 15:17:06 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers MySQL] 3월에 태어난 여성 회원 목록 출력하기</title>
      <link>https://nnindd.tistory.com/66</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131120&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/131120&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;DATE&lt;/code&gt; 타입을 출력하면 &lt;code&gt;1992-03-16 00:00:00&lt;/code&gt;으로 나오기 때문에 &lt;code&gt;DATE_FORMAT(DATE_OF_BIRTH, &quot;%Y-%m-%d&quot;) as DATE_OF_BIRTH&lt;/code&gt;를 사용했다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;%Y&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;4자리 연도&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;%y&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;2자리 연도&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;%M&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;영어 월&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;%m&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;2자리 월&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;%D&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;일+th&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;%d&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;2자리 일&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;DATE&lt;/code&gt; 타입에서 월만 가져오려면 &lt;code&gt;MONTH(컬럼명)&lt;/code&gt;을 사용한다. 이외에 &lt;code&gt;YEAR(대상)&lt;/code&gt;, &lt;code&gt;MONTH(대상)&lt;/code&gt;, &lt;code&gt;DAY()&lt;/code&gt; 아니면 &lt;code&gt;DAYOFMONTH()&lt;/code&gt;가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT MEMBER_ID, MEMBER_NAME, GENDER, DATE_FORMAT(DATE_OF_BIRTH, &quot;%Y-%m-%d&quot;) as DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE GENDER = 'W' 
    and MONTH(DATE_OF_BIRTH) = 3 
    and TLNO is not null
ORDER BY MEMBER_ID;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/66</guid>
      <comments>https://nnindd.tistory.com/66#entry66comment</comments>
      <pubDate>Sat, 20 May 2023 14:47:15 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 1018 체스판 다시 칠하기</title>
      <link>https://nnindd.tistory.com/65</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1018&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1018&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;M,N의 크기에서 8*8로 정사각형을 탐색한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8*8 정사각형이 만들어지면 그 안에서 &lt;code&gt;WBWBWB&lt;/code&gt;, &lt;code&gt;BWBWBW&lt;/code&gt;로 시작하는 경우를 생각하여 일치하지 않는 사각형의 개수를 센다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;WBWBWB&lt;/code&gt;로 시작했으면 다음 행은 &lt;code&gt;BWBWBW&lt;/code&gt;로 탐색해야 하기 때문에, 현재 행이 홀수인지 짝수인지에 따라서 어떤 순서와 비교해야 하는지 설정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 현재 카운트가 최소로 칠해야 하는 사각형의 수를 넘었다면 더이상 탐색할 필요가 없기 때문에 &lt;code&gt;return&lt;/code&gt;했다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1683636436349&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        int M = Integer.parseInt(tokens.nextToken()); //행
        int N = Integer.parseInt(tokens.nextToken()); //열

        char[][] map = new char[M][N];
        for (int i = 0; i &amp;lt; M; i++) {
            map[i] = br.readLine().toCharArray();
        }

        //8 * 8로 만들 수 있는 정사각형만큼 반복
        int row = M - 8 + 1;
        int col = N - 8 + 1;
        int res = Integer.MAX_VALUE;

        for (int i = 0; i &amp;lt; row; i++) {
            for (int j = 0; j &amp;lt; col; j++) {
                res = checkArea(i, j, map, res);
            }
        }
        System.out.println(res);

    }

    private static int checkArea(int row, int col, char[][] map, int res) {
        char[] W = {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'};
        char[] B = {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'};

        //현재 row행 col열에서 시작하여 8*8의 정사각형 확인
        int wcnt = 0; //W로 시작하는 경우 색칠할 사각형 수
        int bcnt = 0; //B로 시작하는 경우 색칠할 사각형 수

        //해당 정사각형에서 색이 일치하지 않는 사각형 개수 확인
        for (int i = 0; i &amp;lt; 8; i++) {
            for (int j = 0; j &amp;lt; 8; j++) {
                char now = map[row + i][col + j];
                if(i%2==0){
                    if(now!=W[j]) wcnt++;
                    if(now!=B[j]) bcnt++;
                }else{
                    if(now!=B[j]) wcnt++;
                    if(now!=W[j]) bcnt++;
                }
                if(wcnt &amp;gt; res &amp;amp;&amp;amp; bcnt &amp;gt; res)
                    return res;
            }
        }
        return Math.min(res, Math.min(wcnt, bcnt));
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>백준</category>
      <category>브루트포스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/65</guid>
      <comments>https://nnindd.tistory.com/65#entry65comment</comments>
      <pubDate>Tue, 9 May 2023 21:58:09 +0900</pubDate>
    </item>
    <item>
      <title>[CodeTree Java] 함께가는 열차</title>
      <link>https://nnindd.tistory.com/64</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/training-field/search/a-train-that-goes-together/description?page=1&amp;amp;pageSize=20&amp;amp;username=&quot;&gt;https://www.codetree.ai/training-field/search/a-train-that-goes-together/description?page=1&amp;amp;pageSize=20&amp;amp;username=&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1682381734703&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;

        int N = Integer.parseInt(br.readLine());

        int[] arr = new int[N];

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            Integer.parseInt(tokens.nextToken());
            int speed = Integer.parseInt(tokens.nextToken());

            arr[i] = speed;
        }

        int res = 1;
        int min = arr[N - 1];

        for (int i = N - 2; i &amp;gt;= 0; i--) {
            if(arr[i] &amp;lt;= min){
                res++;
                min = arr[i];
            }
        }

        System.out.println(res);

    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/CodeTree</category>
      <category>그리디</category>
      <category>코드트리</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/64</guid>
      <comments>https://nnindd.tistory.com/64#entry64comment</comments>
      <pubDate>Tue, 25 Apr 2023 09:15:19 +0900</pubDate>
    </item>
    <item>
      <title>[CodeTree Java] 우유 생산량 경쟁</title>
      <link>https://nnindd.tistory.com/63</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;https://www.codetree.ai/training-field/search/milk-production-competition/description?page=3&amp;amp;pageSize=20&amp;amp;username=&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;100일 만큼의 크기인 &lt;code&gt;days&lt;/code&gt; 배열에 소의 이름과 등락값 저장&lt;/li&gt;
&lt;li&gt;100일만큼 반복문을 돌면서 우유의 등락값 계산&lt;/li&gt;
&lt;li&gt;우유의 최대값을 계산하고 임시 전광판 배열인 &lt;code&gt;temp&lt;/code&gt;에서 최대값으로 우유를 생산한 소의 전광판만 1로 표시해줌&lt;/li&gt;
&lt;li&gt;이전 전광판과 비교해서 달라졌다면 &lt;code&gt;res++&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;전광판 갱신&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1682255732675&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main_우유생산량경쟁 {

    static final StringB= &quot;Bessie&quot;;
    static final StringE= &quot;Elsie&quot;;
    static final StringM= &quot;Mildred&quot;;

    static class Cows{
        String name;
        int upDown;

        public Cows(String name, int upDown) {
            this.name = name;
            this.upDown = upDown;
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;

        int N = Integer.parseInt(br.readLine());
        Cows[] days = new Cows[101];

        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());

            int day = Integer.parseInt(tokens.nextToken());
            String cow = tokens.nextToken();
            int upDown = Integer.parseInt(tokens.nextToken());

            days[day] = new Cows(cow, upDown);
        }

        //가장 처음 날짜는 7갤런씩, 3마리 모두 전광판에 이름을 올림
        int res = 0;
        int[] score = new int[]{7, 7, 7};
        int[] prev = new int[]{1, 1, 1};

        for (int i = 0; i &amp;lt;= 100; i++) {
            if(days[i] == null) continue;

            //우유 등락 계산
            if(days[i].name.equals(B)){
                score[0] += days[i].upDown;
            } else if (days[i].name.equals(E)) {
                score[1] += days[i].upDown;
            }else {
                score[2] += days[i].upDown;
            }

            //최대값 구하기
            int max = Math.max(score[0], Math.max(score[1], score[2]));

            //전광판에 올라갈 최대값만 저장
            int[] temp = new int[3];
            for (int j = 0; j &amp;lt; 3; j++) { //최대값만 저장
                if(score[j] == max) temp[j] = 1;
            }

            //이전 전광판이랑 비교해서 달라졌는지 확인
            boolean flag = false;
            for (int j = 0; j &amp;lt; 3; j++) {
                if(prev[j] != temp[j]) flag = true;
            }
            if(flag) res++;

            //전광판 갱신
            prev = Arrays.copyOf(temp, 3);
        }
        System.out.println(res);
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/CodeTree</category>
      <category>그리디</category>
      <category>정렬</category>
      <category>코드트리</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/63</guid>
      <comments>https://nnindd.tistory.com/63#entry63comment</comments>
      <pubDate>Sun, 23 Apr 2023 22:16:39 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 1439 뒤집기</title>
      <link>https://nnindd.tistory.com/62</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1439&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1439&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0이 연속되는 횟수와, 1이 연속되는 횟수를 구해서 적은 값을 선택한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1681815279638&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main_1439_뒤집기 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String num = br.readLine();

        //0과 1이 연속되지 않는 영역 개수 구함

        int prev = num.charAt(0) - '0'; //처음 값

        //처음 영역 설정
        int zero = prev == 0 ? 1 : 0;
        int one = prev == 1 ? 1 : 0;

        for (int i = 1; i &amp;lt; num.length(); i++) {
            int cur = num.charAt(i) - '0';
            if (prev != cur) {
                prev = cur;
                //현재 들어온 값이 0인지 1인지에 따라 영역 선택
                zero += cur == 0 ? 1 : 0;
                one += cur == 1 ? 1 : 0;
            }
        }

        System.out.println(Math.min(zero, one));
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>그리디</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/62</guid>
      <comments>https://nnindd.tistory.com/62#entry62comment</comments>
      <pubDate>Tue, 18 Apr 2023 19:54:53 +0900</pubDate>
    </item>
    <item>
      <title>[CodeTree Java] 두 단어 중 특정 알파벳</title>
      <link>https://nnindd.tistory.com/61</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;문제 링크&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;a style=&quot;color: #333333;&quot; href=&quot;https://www.codetree.ai/training-field/search/specific-alphabet-of-two-words/submissions?page=3&amp;amp;pageSize=20&amp;amp;username=&quot;&gt;https://www.codetree.ai/training-field/search/specific-alphabet-of-two-words/submissions?page=3&amp;amp;pageSize=20&amp;amp;username=&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;접근 방법&lt;/span&gt;&lt;/h4&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;fox box의 경우는 f, b 경우에는 겹치지 않기 때문에 1을 추가. o와 x는 둘 다 최대 1번씩 나타나기 때문에 1씩 갱신해준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bus car의 경우에는 b는 한번 등장했기에 위에서 +1을 해줘서 총 2가 되고, 나머지의 경우도 1로 갱신이 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코드&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1681734645678&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.StringTokenizer;

public class Main_두단어중특정알파벳 {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int T = Integer.parseInt(br.readLine());

        int[] res = new int[26];
        int[] cnt1, cnt2;

        String left, right;

        for (int i = 0; i &amp;lt; T; i++) {
            StringTokenizer tokens = new StringTokenizer(br.readLine());
            left = tokens.nextToken();
            right = tokens.nextToken();

            cnt1 = new int[26];
            cnt2 = new int[26];

            for (int j = 0; j &amp;lt; left.length(); j++) {
                cnt1[left.charAt(j)-'a']++;
            }
            for (int j = 0; j &amp;lt; right.length(); j++) {
                cnt2[right.charAt(j)-'a']++;
            }

            for (int j = 0; j &amp;lt; 26; j++) {
                res[j] += Math.max(cnt1[j], cnt2[j]);
            }

        }

        for (int i = 0; i &amp;lt; 26; i++) {
            bw.write(res[i]+&quot;\n&quot;);
        }
        bw.flush();
        bw.close();

    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/CodeTree</category>
      <category>그리디</category>
      <category>코드트리</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/61</guid>
      <comments>https://nnindd.tistory.com/61#entry61comment</comments>
      <pubDate>Mon, 17 Apr 2023 21:32:59 +0900</pubDate>
    </item>
    <item>
      <title>[CodeTree Java] 수의 곱셈</title>
      <link>https://nnindd.tistory.com/60</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #6e7781; text-align: start;&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/training-field/search/specific-alphabet-of-two-words/description?page=1&amp;amp;pageSize=20&amp;amp;username=&quot;&gt;https://www.codetree.ai/training-field/search/specific-alphabet-of-two-words/description?page=1&amp;amp;pageSize=20&amp;amp;username=&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;접근 방법&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;a, b, c와 세 수를 각각 곱한 값 7개를 만든다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;리스트에 담아 큰 수 먼저 정렬, 그 다음으로 홀수를 정렬&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;정렬을 2번 하는 것이 비효율적이라 생각이 들었다.&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;스터디원의 얘기를 들어보니 홀수가 없다면 전부 곱하고, 홀수가 있다면 홀수만 계산하는 방법을 선택했다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;코드&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1681734538814&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class Main_수의곱셈 {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer tokens = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(tokens.nextToken());
        int b = Integer.parseInt(tokens.nextToken());
        int c = Integer.parseInt(tokens.nextToken());

        ArrayList&amp;lt;Integer&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        list.add(a);
        list.add(b);
        list.add(c);
        list.add(a * b);
        list.add(a * c);
        list.add(b * c);
        list.add(a * b * c);

        //큰 수 정렬
        Collections.sort(list, Collections.reverseOrder());

        //홀수 정렬
        Collections.sort(list, ((x, y) -&amp;gt;{
            if(x%2==1 &amp;amp;&amp;amp; y%2==0){
                return x-y;
            }
            return y-x;
        }));

        System.out.println(list.get(0));

    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/CodeTree</category>
      <category>그리디</category>
      <category>코드트리</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/60</guid>
      <comments>https://nnindd.tistory.com/60#entry60comment</comments>
      <pubDate>Mon, 17 Apr 2023 21:29:22 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 7562 나이트의 이동</title>
      <link>https://nnindd.tistory.com/59</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/7562&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/7562&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최단 시간에 도착해야 하기 때문에 bfs&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나이트가 갈 수 있는 방향을 8방으로 지정해두고 이동 횟수를 추가하여 진행&lt;/p&gt;
&lt;pre id=&quot;code_1681043186814&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;

        int T = Integer.parseInt(br.readLine());

        while (T-- &amp;gt; 0) {
            int l = Integer.parseInt(br.readLine());

            int[][] map = new int[l][l];

            tokens = new StringTokenizer(br.readLine());
            int x1 = Integer.parseInt(tokens.nextToken());
            int y1 = Integer.parseInt(tokens.nextToken());

            tokens = new StringTokenizer(br.readLine());
            int x2 = Integer.parseInt(tokens.nextToken());
            int y2 = Integer.parseInt(tokens.nextToken());

            //나이트의 이동 방향 8방
            System.out.println(bfs(x1, y1, x2, y2, l));
        }
    }

    private static int bfs(int x1, int y1, int x2, int y2, int l) {
        int res = -1;
        Queue&amp;lt;int[]&amp;gt; q = new ArrayDeque&amp;lt;&amp;gt;();
        q.offer(new int[]{x1, y1, 0});

        boolean[][] v = new boolean[l][l];
        v[x1][y1] = true;

        while (!q.isEmpty()){
            int[] c = q.poll();

            if(c[0] == x2 &amp;amp;&amp;amp; c[1] == y2){
                res = c[2];
                break;
            }

            for (int d = 0; d &amp;lt; 8; d++) {
                int nx = c[0] + dir[d][0];
                int ny = c[1] + dir[d][1];

                if(!isRange(nx, ny, l) || v[nx][ny]) continue;
                v[nx][ny] = true;
                q.offer(new int[]{nx, ny, c[2]+1});
            }
        }
        return res;
    }


    static int[][] dir = {
            {-2, -1}, {-2, 1},
            {-1, -2}, {1, -2},
            {2, -1}, {2, 1},
            {-1, 2}, {1, 2}};

    private static boolean isRange(int x, int y, int l) {
        if (x &amp;lt; 0 || x &amp;gt;= l || y &amp;lt; 0 || y &amp;gt;= l) return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/59</guid>
      <comments>https://nnindd.tistory.com/59#entry59comment</comments>
      <pubDate>Sun, 9 Apr 2023 21:27:42 +0900</pubDate>
    </item>
    <item>
      <title>[CodeTree Java] 코드트리 빵</title>
      <link>https://nnindd.tistory.com/58</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;문제 링크&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;https://www.codetree.ai/training-field/frequent-problems/codetree-mon-bread/description?page=3&amp;amp;pageSize=20&amp;amp;username=&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;접근 방법&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;위치 배열을 2차원 배열로 사용했다. &lt;code&gt;[사람수][편의점/현위치]&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;한번 이동할때마다 이 사람이 베이스캠프에 배정되어야 하는지, 편의점에 도착했는지를 확인해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;자기 차례가 현재 시간보다 크면 더 이상 탐색할 필요가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이동할때에는 어느 방향으로 가야 하는지를 처음에 몰랐다. 스터디에서 bfs로 가야 하는 방향을 구하려면, 처음에 방향에 대한 값을 그대로 유지하면서 도착지까지 bfs로 구한다. 그래서 q에 넣을 때 처음 4방향이 범위에 맞고 갈 수 있는 방향인지 확인한 다음 큐에 모두 넣었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 부분을 생각하지 못해서(그리고 그 외 코드 오류의 이유로) 44%에서 시간 초과가 났으나 결국 고쳤다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;편의점에 도착했는지 확인할 때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;code&gt;if (pos[i][0].x == pos[i][1].x &amp;amp;&amp;amp; pos[i][0].y == pos[i][1].y)&lt;/code&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;code&gt;if (pos[i][0] == pos[i][1])&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;이 두개가 같은 동작이 되는 줄 알고 후자로 썼다가 메모리 초과가 생겼다. 자바에서 객체에 대한 비교는 메모리 주소를 비교하기 때문에 땡!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;또한, 처음에는 베이스캠프를 전부 구해두고 시작하려 했는데 다른 부분과 겹쳐져 오류가 났다. 베이스캠프를 전부 구하고 시작해도 되는지 궁금하다. 다음에 시간이 날 때 한번 풀어봐야겠다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코드&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1680185953533&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;

public class Main {
    static int N, M, map[][], finish;
    static Pos pos[][];
    static int[][] dir = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}};

    static class Pos {
        int x, y, d;

        public Pos(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public Pos(int x, int y, int d) {
            this.x = x;
            this.y = y;
            this.d = d;
        }
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        //입력 받기
        N = Integer.parseInt(tokens.nextToken()); //격자 크기
        M = Integer.parseInt(tokens.nextToken()); //사람 수
        map = new int[N][N]; //맵
        pos = new Pos[M][2]; //편의점 위치, 현재 위치

        //map input
        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; N; j++) {
                map[i][j] = Integer.parseInt(tokens.nextToken());
            }
        }

        //store input
        for (int i = 0; i &amp;lt; M; i++) {
            tokens = new StringTokenizer(br.readLine());
            pos[i][0] = new Pos(Integer.parseInt(tokens.nextToken()) - 1, Integer.parseInt(tokens.nextToken()) - 1);
        }

        int t = 0;
        finish = 0;
        while (finish &amp;lt; M) {
            move(t++);
        }
        System.out.println(t);

    }

    private static void move(int t) {
        //한 타임마다 모든 사람 이동
        for (int i = 0; i &amp;lt; M; i++) {
            //자기 차례가 되지 않아 격자 밖이라면 더이상 진행 안함
            if (i &amp;gt; t) return;
            //t == i이고 pos 현위치가 null이라면 베이스캠프 배정
            if (i == t &amp;amp;&amp;amp; pos[i][1] == null) {
                getBaseCamp(i); //i번째 사람이 가려는 편의점에서 가장 가까운 베이스캠프 정함
            } else { //아니라면 최단 거리로 갈 방향 선택해서 이동
                if(pos[i][1] == null) continue; //이미편의점에 도착한 사람
                int d = goFast(i); //최단 거리로 갈 방향 구해옴
                //이동
                pos[i][1].x += dir[d][0];
                pos[i][1].y += dir[d][1];
                //편의점에 도착했는지 확인
                if (pos[i][0].x == pos[i][1].x &amp;amp;&amp;amp; pos[i][0].y == pos[i][1].y) {
                    int cx = pos[i][0].x;
                    int cy = pos[i][0].y;
                    map[cx][cy] = 9; //맵에 방문 못하게 처리
                    pos[i][1] = null; //자신은 비움
                    finish++; //편의점에 도착한 사람 처리
                }
            }

        }

    }

    private static int goFast(int idx) { //현위치
        //현 위치에서 목적지 편의점까지 가장 빠른 방향을 구함
        Pos dest = pos[idx][0]; //도착하고자 하는 곳
        Pos start = pos[idx][1]; //현재 위치
        Deque&amp;lt;Pos&amp;gt; q = new ArrayDeque&amp;lt;&amp;gt;();
        boolean[][] v = new boolean[N][N];

        //4방향 전부 넣음
        for (int d = 0; d &amp;lt; 4; d++) {
            int nx = start.x + dir[d][0];
            int ny = start.y + dir[d][1];
            if(!isRange(nx, ny) || map[nx][ny] == 9) continue;
            q.offer(new Pos(nx, ny, d));
            v[nx][ny] = true;
        }

        int direction = -1;

        while (!q.isEmpty()) {
            Pos cur = q.poll();
            if (cur.x == dest.x &amp;amp;&amp;amp; cur.y == dest.y) {
                //목적지 방향을 구함
                direction = cur.d;
                break;
            }

            for (int d = 0; d &amp;lt; 4; d++) {
                int nx = cur.x + dir[d][0];
                int ny = cur.y + dir[d][1];

                if (!isRange(nx, ny) || map[nx][ny] == 9 || v[nx][ny]) continue;
                q.offer(new Pos(nx, ny, cur.d)); //방향 처음 그대로 저장
                v[nx][ny] = true;
            }
        }
        return direction;
    }

    //베이스 캠프 정하기 : bfs, 주어진 방향 순서대로 이동 후 가장 먼저 도착하는 곳이 베이스캠프(상좌우하)
    private static void getBaseCamp(int idx) {
        Pos s = pos[idx][0];
        Deque&amp;lt;Pos&amp;gt; q = new ArrayDeque&amp;lt;&amp;gt;();
        q.offer(s);
        boolean[][] v = new boolean[N][N];
        v[s.x][s.y] = true;

        while (!q.isEmpty()) {
            Pos cur = q.poll();

            for (int d = 0; d &amp;lt; 4; d++) {
                int nx = cur.x + dir[d][0];
                int ny = cur.y + dir[d][1];

                if (!isRange(nx, ny) || map[nx][ny] == 9 || v[nx][ny]) continue;
                //0이면 다음 위치로
                if (map[nx][ny] == 0) {
                    q.offer(new Pos(nx, ny));
                    v[nx][ny] = true;
                }
                //1이면 베이스 캠프 선택 완료
                if (map[nx][ny] == 1) {
                    pos[idx][1] = new Pos(nx, ny); //현재 위치 갱신
                    map[nx][ny] = 9; //맵에서 사용 못하게 처리
                    return;
                }
            }
        }
    }

    private static boolean isRange(int x, int y) {
        if (x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= N) return false;
        return true;
    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/CodeTree</category>
      <category>BFS</category>
      <category>구현</category>
      <category>시뮬레이션</category>
      <category>코드트리</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/58</guid>
      <comments>https://nnindd.tistory.com/58#entry58comment</comments>
      <pubDate>Thu, 30 Mar 2023 23:25:54 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 4673 셀프 넘버</title>
      <link>https://nnindd.tistory.com/57</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;문제링크&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/4673&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/4673&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;접근 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1부터 10000까지 주어진 숫자를 만든다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10000은 10001이 되고, 9999는 9999+9+9+9+9 = 10035이 되기 때문에 숫자 배열을 11000까지 미리 생성해줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만들어진 숫자를 인덱스로 잡아 값을 증가시켜준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1부터 10000까지 탐색하면서 0인 곳을 출력하면 됨.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1656773517815&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb = new StringBuilder();
        int sum;
        //9999 -&amp;gt; 9999+9+9+9+9 = 10035
        int[] arr = new int[11000];
        for (int i = 1; i &amp;lt;= 10000; i++) {
            //1~10000까지 숫자를 다 만듦
            sum = 0;
            String str = Integer.toString(i);
            for (int j = 0; j &amp;lt; str.length(); j++) {
                sum += str.charAt(j) - '0';
            }
            sum += i;
            arr[sum]++;
        }
        for (int i = 1; i &amp;lt;= 10000; i++) {
            if(arr[i] == 0){
                sb.append(i).append(&quot;\n&quot;);
            }
        }
        
        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>구현</category>
      <category>백준</category>
      <category>완전탐색</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/57</guid>
      <comments>https://nnindd.tistory.com/57#entry57comment</comments>
      <pubDate>Fri, 24 Mar 2023 22:13:20 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers Java] 이모티콘 할인행사</title>
      <link>https://nnindd.tistory.com/56</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/150368&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/150368&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이모티콘 마다 할인율을 dfs로 구함&lt;/li&gt;
&lt;li&gt;사용자 수만큼 반복
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이모티콘 수만큼 반복
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이모티콘 할인율 &amp;ge; 사용자 라면 할인율을 계산해서 지불할 금액에 더함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;지불할 금액 &amp;ge; 제한금액이면 이모티콘 플러스 가입&lt;/li&gt;
&lt;li&gt;아니라면 판매액에 지불할 금액 더함&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;결과값이랑 비교
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이모티콘 플러스 사용자가 많다면 갱신&lt;/li&gt;
&lt;li&gt;이모티콘 플러스 사용자가 같다면 판매액이 더 많은 것 갱신&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블라인드 코테에선 못 풀었는데 끝나고 반년 뒤에 푸니까 풀렸다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할인율을 배열로 선언할 필요 없이 for문의 i를 40 30 20 10으로 줄어들게 해도 된다.&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;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;class Solution {
    static int len, resEmo, resSell;
    static int[] r = {40, 30, 20, 10};
    static int e[], u[][];
    public static int[] solution(int[][] users, int[] emoticons) {
        e = emoticons;
        u = users;
        len = emoticons.length;
        resEmo = 0;
        resSell = 0;

        //이모티콘마다 할인율 10, 20, 30, 40 중 선택
        dfs(0, emoticons.length, new int[emoticons.length]);

        System.out.println(resEmo+&quot; &quot;+resSell);

        return new int[]{resEmo, resSell};
    }
    private static void dfs(int dept, int len, int[] s){
        //종료조건
        if(dept == len){
            calcMember(s);
            return;
        }

        //이모티콘 선택
        for (int i = 0; i &amp;lt; 4; i++) {
            s[dept] = r[i]; //할인율 선택
            dfs(dept+1, len, s);
        }
    }

    private static void calcMember(int[] s) {

        int emoPlus = 0;
        int totalSell = 0;

        //사용자 수만큼 for, 구매할 사람 선택
        for(int[] user : u){
            int personRate = user[0];
            int limitMoney = user[1];

            //한 사람이 지불할 가격
            int money = 0;
            //살 이모티콘 선택
            for (int i = 0; i &amp;lt; len; i++) {
                if(s[i] &amp;gt;= personRate){ //일정 비율 이상 할인이라면
                    //살 돈 계산
                    money += e[i] * (100-s[i]) / 100;
                }
            }//살 이모티콘 계산 끝

            //이모티콘 플러스 가입 여부 확인
            if(money &amp;gt;= limitMoney){
                //이모티콘 플러스 가입
                emoPlus++;
            }else{
                totalSell += money; //판매 총액 갱신
            }
        }

        //최종 이모티콘 플러스 가입자, 판매총액 비교
        if(resEmo &amp;lt; emoPlus){
            resEmo = emoPlus;
            resSell = totalSell;
        }else if(resEmo == emoPlus &amp;amp;&amp;amp; resSell &amp;lt; totalSell){
            resSell = totalSell;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>프로그래머스</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/56</guid>
      <comments>https://nnindd.tistory.com/56#entry56comment</comments>
      <pubDate>Thu, 23 Mar 2023 21:57:57 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 16953 A &amp;rarr; B</title>
      <link>https://nnindd.tistory.com/55</link>
      <description>&lt;h3&gt;문제 링크&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/16953&quot;&gt;https://www.acmicpc.net/problem/16953&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;접근 방법&lt;/h3&gt;
&lt;p&gt;dfs를 사용한다.&lt;br&gt;종료 조건은 A,B가 같은 경우 최소 횟수를 갱신하고 리턴&lt;br&gt;dfs를 타는 부분은 2를 곱할때, 1을 뒤에 붙일때.&lt;/p&gt;
&lt;p&gt;input이 10^9까지 들어오기 때문에 long으로 처리했다.&lt;br&gt;백트래킹은 횟수와 A의 크기를 비교해서 처리했다.&lt;/p&gt;
&lt;h3&gt;코드&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    static int res;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        Long A = Long.parseLong(tokens.nextToken());
        Long B = Long.parseLong(tokens.nextToken());

        res = Integer.MAX_VALUE;

        dfs(A, B, 1);

        System.out.println(res == Integer.MAX_VALUE ? -1 : res);
    }
    private static void dfs(long A, long B, int cnt) {
        if (res &amp;lt; cnt || A &amp;gt; B) { //백트래킹
            return;
        }

        if (B == A) {
            res = Math.min(res, cnt);
            return;
        }
        //2를 곱함
        dfs(A * 2, B, cnt + 1);
        //끝에 1을 붙임
        dfs(Long.parseLong(Long.toString(A) + &amp;quot;1&amp;quot;), B, cnt + 1);
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>그리디</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/55</guid>
      <comments>https://nnindd.tistory.com/55#entry55comment</comments>
      <pubDate>Thu, 23 Mar 2023 21:50:24 +0900</pubDate>
    </item>
    <item>
      <title>[Codetree Java] 꼬리잡기놀이</title>
      <link>https://nnindd.tistory.com/54</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/training-field/frequent-problems/tail-catch-play/description?page=3&amp;amp;pageSize=20&amp;amp;username=nnindd&amp;amp;discussionRowsPerPage=5&amp;amp;discussionPage=1&quot;&gt;https://www.codetree.ai/training-field/frequent-problems/tail-catch-play/description?page=3&amp;amp;pageSize=20&amp;amp;username=nnindd&amp;amp;discussionRowsPerPage=5&amp;amp;discussionPage=1&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 순서는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1의 위치를 리스트에 저장&lt;/li&gt;
&lt;li&gt;k번 게임 실행
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이동 (M만큼 for)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;바뀐 1의 위치 갱신&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;공 던지는 4분면, 행, 열, 방향 구하기&lt;/li&gt;
&lt;li&gt;공 던지기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;맞음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;맞았다면 몇번째 사람인지 구하기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;맵의 크기만큼 반복문 돌면서 1인 곳 찾기&lt;/li&gt;
&lt;li&gt;1이면 해당 팀원 위치 리스트 받아오기&lt;/li&gt;
&lt;li&gt;그 리스트에 맞은 사람 위치 있는지 확인&lt;/li&gt;
&lt;li&gt;있으면 맵에서 1, 3 변경&lt;/li&gt;
&lt;li&gt;있으면 머리 리스트에서 1 위치 갱신&lt;/li&gt;
&lt;li&gt;인덱스 제곱 계산해서 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;안 맞음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공 멈추기 않고 던지기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길다..&lt;br /&gt;우욱..&lt;br /&gt;깔끔하게 작성하려고 함수를 다 빼면서 작성하다가 헷갈려서 생각나는대로 적었다.&lt;br /&gt;input이 적기 때문에 전부 확인해봐도 되었고, 시간복잡도는 O(K*N^2)라니 1000*20^2면.. 할만함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;어려웠던 부분&lt;/h4&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;일단 4분면 중 한곳에 위치할 수 있게 하고, 방향에 따라서 N 안에서 어디에 위치하는지...&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지나갈 수 있는 길이 1 2 2 3 4 4 4 이런 형식이 아니라 1 2 2 2 2 3 으로 끝나는 경우를 생각해봐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1이 이동할 땐 4인 곳으로 가는 것이 아니라 2가 아닌 곳으로 간다고 생각해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 생각을 듣고 아득해짐......&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;

public class Main {

    static int N, M, K, map[][], total;
    static ArrayList&amp;lt;int[]&amp;gt; first; //1의 위치
    static int[][] dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        StringTokenizer tokens = new StringTokenizer(br.readLine());
        N = Integer.parseInt(tokens.nextToken()); //격자 크기
        M = Integer.parseInt(tokens.nextToken()); //팀의 개수
        K = Integer.parseInt(tokens.nextToken()); //라운드 수

        map = new int[N][N]; //맵
        total = 0;

        first = new ArrayList&amp;lt;&amp;gt;();
        for (int i = 0; i &amp;lt; N; i++) {
            tokens = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; N; j++) {
                map[i][j] = Integer.parseInt(tokens.nextToken());
                if (map[i][j] == 1) { //1의 위치 저장
                    first.add(new int[]{i, j});
                }
            }
        }//end input

        for (int i = 0; i &amp;lt; K; i++) {
            total += play(i);
        }

        bw.write(total + &quot;&quot;);
        bw.flush();
        bw.close();
    }

    private static int play(int k) {
        //이동
        for (int i = 0; i &amp;lt; M; i++) {
            int[] cur = move(first.get(i));
            //바뀐 1의 위치 갱신해주기
            first.set(i, cur);
        }

        //공던짐
        int[] rcd = getRowColDirection(k);
        int area = rcd[0];
        int row = rcd[1];
        int col = rcd[2];
        int d = rcd[3];

        int x = row;
        int y = col;
        int temp = 0;
        while (isRange(x, y)) { //범위 안 벗어날때까지
            if (map[x][y] != 0 &amp;amp;&amp;amp; map[x][y] != 4) {
                //맞은 사람 몇번째인지 구하기 + 점수 갱신 + 머리 꼬리 바꾸기
                temp = checkIndex(x, y);
                break;
            }
            //안 맞았으면 다음방향
            x += dir[d][0];
            y += dir[d][1];
        }
        return temp;
    }

    private static int checkIndex(int x, int y) {
        //몇번째 사람인지 구하기

        ArrayList&amp;lt;int[]&amp;gt; list;

        //1인 부분 확인
        for (int i = 0; i &amp;lt; N; i++) {
            for (int j = 0; j &amp;lt; N; j++) {
                if (map[i][j] != 1) continue;

                //이 팀원 리스트 불러옴
                list = getTeamPosition(new int[]{i, j});

                //이 팀원 중 이사람이 있는지 확인
                for (int k = 0; k &amp;lt; list.size(); k++) {
                    if (list.get(k)[0] == x &amp;amp;&amp;amp; list.get(k)[1] == y) {
                        //머리 꼬리 맵에서 바꾸기
                        int[] front = list.get(0);
                        int[] back = list.get(list.size()-1);
                        int temp = map[front[0]][front[1]];
                        map[front[0]][front[1]] = map[back[0]][back[1]];
                        map[back[0]][back[1]] = temp;

                        //머리 리스트에 머리 변경
                        for (int l = 0; l &amp;lt; first.size(); l++) {
                            int[] head = first.get(l);
                            if(head[0] == front[0] &amp;amp;&amp;amp; head[1] == front[1]){
                                first.set(l, back); //꼬리를 머리로 바꿈
                            }
                        }
                        //점수 반환
                        return (k + 1) * (k + 1);
                    }
                }
            }
        }
        return 0;
    }

    private static int[] getRowColDirection(int k) {
        //던진 위치에 따라서 행, 열, 방향을 구함
        // 좌 하 우 상 순서로 0 1 2 3
        int area, row, col, dir; //4변 중 위치, 어느 행/열에 있는지, 공던지는 방향

        area = (k / N) % 4; //4변 중 어디인지 구하기

        if (area == 0) {
            col = 0;
            row = k % N;
            dir = 3;
        } else if (area == 1) {
            row = N - 1;
            col = k % N;
            dir = 0;
        } else if (area == 2) {
            row = N - (k % N) - 1;
            col = N - 1;
            dir = 2;
        } else {
            row = 0;
            col = N - (k % N) - 1;
            dir = 1;
        }

        return new int[]{area, row, col, dir};
    }

    private static int[] move(int[] n1) {
        //팀원 리스트 구함
        ArrayList&amp;lt;int[]&amp;gt; list = getTeamPosition(n1);

        //한명씩 이동 -&amp;gt; 첫번째만 갈 곳 정하고 그 다음부턴 이전의 위치로 변경
        //첫번째 이동
        int[] one = n1;//첫번째가 이동한 위치 저장 (1이 3으로 이동했을 때 4로 덮어씌워지는것 방지)
        for (int d = 0; d &amp;lt; 4; d++) {
            int nx = n1[0] + dir[d][0];
            int ny = n1[1] + dir[d][1];

            //범위 내이고 2가 아닐때
            if (!isRange(nx, ny) || map[nx][ny] == 0) continue;
            if (map[nx][ny] != 2) {
                map[nx][ny] = map[n1[0]][n1[1]]; //1번은 0,2가 아닌 곳으로 이동
                one = new int[]{nx, ny};
                break; //더 볼 것 없음
            }
        }

        int[] next = n1; //다음 사람이 이동할 곳
        //남은 위치 이동
        for (int i = 1; i &amp;lt; list.size(); i++) {
            //위치 이동
            int[] cur = list.get(i);
            map[next[0]][next[1]] = map[cur[0]][cur[1]]; //앞의 사람이 옮겨간 자리에 채우기
            if (i == list.size() - 1) {
                map[next[0]][next[1]] = 3; //마지막 값이라면 1이 덮어씌운 값으로 들어가는 것 방지3 처리
            }
            map[cur[0]][cur[1]] = 4; //자신이 있던 곳 빈곳 처리
            next = cur; //다음 채울 곳 갱신
        }
        //1이 3으로 이동했을 때 마지막에 4로 덮어 씌워지는 것 방지
        map[one[0]][one[1]] = 1;

        //1의 위치 갱신
        return one;
    }

    private static ArrayList&amp;lt;int[]&amp;gt; getTeamPosition(int[] n1) {
        Queue&amp;lt;int[]&amp;gt; q = new ArrayDeque&amp;lt;&amp;gt;(); //방문확인
        q.offer(n1);
        boolean[][] v = new boolean[N][N];
        v[n1[0]][n1[1]] = true;
        ArrayList&amp;lt;int[]&amp;gt; list = new ArrayList&amp;lt;&amp;gt;(); //팀들 위치 저장 리스트
        list.add(n1);

        //bfs로 팀원 위치 구함
        while (!q.isEmpty()) {
            int[] cur = q.poll();

            for (int d = 0; d &amp;lt; 4; d++) {
                int nx = cur[0] + dir[d][0];
                int ny = cur[1] + dir[d][1];

                if (!isRange(nx, ny) || map[nx][ny] == 0 || map[nx][ny] == 4 || v[nx][ny]) continue;
                //나의 값보다 같거나 하나 클때만 이동
                if ((map[cur[0]][cur[1]] == 1 &amp;amp;&amp;amp; map[nx][ny] == 2)
                        || (map[cur[0]][cur[1]] == 2 &amp;amp;&amp;amp; map[cur[0]][cur[1]] &amp;lt;= map[nx][ny])) {
                    //1이면 2로만 가고, 2라면 같거나 큰곳으로만
                    v[nx][ny] = true;
                    q.offer(new int[]{nx, ny});
                    list.add(new int[]{nx, ny}); //팀원 위치 저장
                }
            }
        }
        return list;
    }

    private static boolean isRange(int x, int y) {
        if (x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= N) return false;
        return true;
    }


}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/CodeTree</category>
      <category>codetree</category>
      <category>꼬리잡기놀이</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/54</guid>
      <comments>https://nnindd.tistory.com/54#entry54comment</comments>
      <pubDate>Wed, 22 Mar 2023 22:19:19 +0900</pubDate>
    </item>
    <item>
      <title>[Error] Permissions 0644 for 'xxx.pem' are too open.</title>
      <link>https://nnindd.tistory.com/53</link>
      <description>&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'xxx.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key &quot;xxx.pem&quot;: bad permissions
ubuntu@xxx.p.ssafy.io: Permission denied (publickey).
lost connection&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ec2 서버에서 다른 ec2 서버로 이미지를 전송하기 위해 다음과 같은 명령어를 사용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;scp -i xxx.pem test.png ubuntu@xxx.p.ssafy.io:/디렉토리경로&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ssh -i xxx.pem&lt;/code&gt; 에서도 같은 문제가 발생했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pem 키의 권한을 변경해줘야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;chmod 400 xxx.pem&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;chmod 400 xxx.pem
xxx@CLUSTER:~/data$ sh test.sh
test.png                                                     100%  321KB  72.1MB/s   00:00&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;권한을 변경한 결과 잘 실행됐다.&lt;/p&gt;</description>
      <category>Project</category>
      <category>EC2</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/53</guid>
      <comments>https://nnindd.tistory.com/53#entry53comment</comments>
      <pubDate>Wed, 22 Mar 2023 11:00:42 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 10610 30</title>
      <link>https://nnindd.tistory.com/52</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 링크&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10610&quot;&gt;https://www.acmicpc.net/problem/10610&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;접근 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 어렵게 생각했는데 30의 배수를 구하는 방법을 생각하면 된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;끝은 0으로 끝나야 함&lt;/li&gt;
&lt;li&gt;각 자리수의 합이 3의 배수여야 한다&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 입력 받은 수를 문자열로 받아 &lt;code&gt;char&lt;/code&gt; 배열로 만들고 정렬했다.&lt;br /&gt;내림차순으로 접근해서 가장 큰 수를 만들었음.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드&lt;/h3&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        //0이 포함되어야 30의 배수를 만들 수 있다.
        //각 자리의 합이 3의 배수여야 30의 배수를 만들 수 있다.

        //1. 입력받은 문자열을 0~9까지의 카운트 배열에 입력하고 총합 계산
        String num = br.readLine();

        char[] arr = num.toCharArray();
        Arrays.sort(arr);

        int sum = 0;
        StringBuilder sb = new StringBuilder();

        for (int i = num.length() - 1; i &amp;gt;= 0; i--) {
            sum += arr[i] - '0';
            sb.append(arr[i] - '0');
        }

        //2. 0을 포함하는지, 총합이 3의 배수인지 확인
        System.out.println(num.contains(&quot;0&quot;) &amp;amp;&amp;amp; sum % 3 == 0 ? sb : -1);
    }

}
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>그리디</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/52</guid>
      <comments>https://nnindd.tistory.com/52#entry52comment</comments>
      <pubDate>Tue, 21 Mar 2023 22:50:29 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 13305 주유소</title>
      <link>https://nnindd.tistory.com/51</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 링크&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/13305&quot;&gt;https://www.acmicpc.net/problem/13305&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;접근 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음~&lt;br /&gt;&lt;b&gt;잘못 생각한 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;거리 중 가장 싼 도시를 고름&lt;/li&gt;
&lt;li&gt;그 도시에서 남은 거리 모두 충전&lt;/li&gt;
&lt;li&gt;다른 거리는 다음 도시로 가기 위해 필요한 거리 만큼만 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;➡️ 이랬더니 17점 나옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;올바른 풀이&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;순서대로 탐색하면서 이전보다 싸면 최소값으로 갱신&lt;/li&gt;
&lt;li&gt;해당 도시의 거리만큼 가장 싼 곳에서 충전&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 첫번째 도시를 최소값으로 설정하고, 두번째 도시로 가기 위한 비용을 설정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문은 2번째 도시부터 N만큼 탐색한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;input 반복문을 두번 돌리고 마지막에 다시 반복문을 돌면서 탐색을 했는데, 도시 주유 비용 입력 받으면서 한번에 처리 해도 돼서 코드를 수정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간은 O(N)이 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드&lt;/h3&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        //도시 사이 거리
        long[] dist = new long[N - 1];
        for (int i = 0; i &amp;lt; N - 1; i++) {
            dist[i] = Integer.parseInt(tokens.nextToken());
        }

        tokens = new StringTokenizer(br.readLine());
        int cost = Integer.parseInt(tokens.nextToken()); //가장 처음 값

        //초기값 설정. 처음 도시는 다음 거리만큼 충전해야 함
        long min = cost;
        long result = min * dist[0];

        //두번째 도시부터 설정
        for (int i = 1; i &amp;lt; N-1; i++) {
            cost = Integer.parseInt(tokens.nextToken());
            min = cost &amp;lt; min ? cost : min; //이전 값이랑 비교해서 싼 값 저장
            result += (min * dist[i]);
        }// end input

        System.out.println(result);

    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>그리디</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/51</guid>
      <comments>https://nnindd.tistory.com/51#entry51comment</comments>
      <pubDate>Fri, 17 Mar 2023 21:55:18 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 1946 신입 사원</title>
      <link>https://nnindd.tistory.com/50</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 링크&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1946&quot;&gt;https://www.acmicpc.net/problem/1946&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;접근 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 문제 이해를 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1차 점수로 정렬해서 1등을 뽑고 2차 첨수로 정렬했을 때 1등의 2차 점수보다 낮은 사람을 다 탈락시키면 되는건가 싶었는데 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정올에서 같은 문제가 있어 반례를 확인해볼 수 있었는데, 다음과 같다&lt;/p&gt;
&lt;pre id=&quot;code_1678972845152&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;input
10
9 1
5 7
1 8
2 4
10 5
4 10
7 6
3 2
6 9
8 3

output
4

나
7&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘못 생각했던 부분은 1차 점수로 정렬하고 2차 점수로 재정렬하는 것이 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1차 기준으로 정렬 후 2차에서 2차 점수가 가장 높은 것을 갱신해나가면서 그보다 낮은 지원자들을 빼는 방법이었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드&lt;/h3&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;package BOJ;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main_1946_신입사원 {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());
        int N;

        while (T--&amp;gt;0){
            N = Integer.parseInt(br.readLine());

            int[][] arr = new int[N][2];

            for (int i = 0; i &amp;lt; N; i++) {
                tokens = new StringTokenizer(br.readLine());
                //서류, 면접
                arr[i][0] = Integer.parseInt(tokens.nextToken());
                arr[i][1] = Integer.parseInt(tokens.nextToken());
            }

            //서류 기준 오름차순 정렬
            Arrays.sort(arr, (a, b) -&amp;gt; a[0]-b[0]);

            int cnt = N;
            int max = arr[0][1]; //서류 1등의 면접 점수 저장
            for (int i = 1; i &amp;lt; N; i++) {
                if(arr[i][1] &amp;lt; max){//현재 1등의 등수보다 i의 면접 등수가 높으면 최대값 변경
                    max = arr[i][1];
                }else{ //현재 1등의 면접 점수보다 낮으면 선발 안 함
                    cnt--;
                }
            }
            sb.append(cnt).append(&quot;\n&quot;);
        }
        System.out.println(sb);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckYpXl/btr4jKMg8mY/q5N3Bs4OZp8gKm5dbb8lM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckYpXl/btr4jKMg8mY/q5N3Bs4OZp8gKm5dbb8lM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckYpXl/btr4jKMg8mY/q5N3Bs4OZp8gKm5dbb8lM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckYpXl%2Fbtr4jKMg8mY%2Fq5N3Bs4OZp8gKm5dbb8lM1%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;1148&quot; height=&quot;180&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&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;1차인 서류 등수를 인덱스로 사용하고 2차 면접 점수를 값으로 사용하면 정렬할 필요가 없어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 생각 해내는 뇌..당장훔쳐...&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드2&lt;/h3&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;package BOJ;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main_1946_신입사원 {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());
        int N;

        while (T--&amp;gt;0){
            N = Integer.parseInt(br.readLine());

            int[] arr = new int[N+1];

            for (int i = 0; i &amp;lt; N; i++) {
                tokens = new StringTokenizer(br.readLine());
                //서류, 면접
                int idx = Integer.parseInt(tokens.nextToken());
                int val = Integer.parseInt(tokens.nextToken());

                arr[idx] = val;
            }

            //서류 기준 오름차순 정렬
            int top = arr[1];
            int cnt = 1; //서류 1등

            for (int i = 2; i &amp;lt;= N; i++) {
                if(arr[i] &amp;lt; top){
                    top = arr[i];
                    cnt++;
                }
            }
            sb.append(cnt).append(&quot;\n&quot;);
        }
        System.out.println(sb);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q27Lk/btr4fymizKb/VbgCCaF26h2fEUCWP0saw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q27Lk/btr4fymizKb/VbgCCaF26h2fEUCWP0saw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q27Lk/btr4fymizKb/VbgCCaF26h2fEUCWP0saw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq27Lk%2Fbtr4fymizKb%2FVbgCCaF26h2fEUCWP0saw0%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;1168&quot; height=&quot;216&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만족&lt;/p&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>그리디</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/50</guid>
      <comments>https://nnindd.tistory.com/50#entry50comment</comments>
      <pubDate>Thu, 16 Mar 2023 22:28:34 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 10162 전자레인지</title>
      <link>https://nnindd.tistory.com/49</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;문제 링크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10162&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/10162&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번 나누고 나머지를 T에 갱신시켜주면 되는 문제.&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;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1678969404087&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package BOJ;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main_10162_전자레인지 {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());
        int[] arr = {300, 60, 10};

        for (int i = 0; i &amp;lt; 3; i++) {
            sb.append(T / arr[i]).append(&quot; &quot;);
            T %= arr[i];
        }

        if (T != 0) {
            sb.delete(0, sb.length()).append(-1);
        }
        System.out.println(sb);

    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>그리디</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/49</guid>
      <comments>https://nnindd.tistory.com/49#entry49comment</comments>
      <pubDate>Thu, 16 Mar 2023 21:23:41 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 1789 수들의 합</title>
      <link>https://nnindd.tistory.com/48</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;문제링크&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1789&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1789&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;합이 S라면 1부터 N까지 더하며 S가 넘지 않을때까지 반복한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;input은&amp;nbsp;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;S(1 &amp;le; S &amp;le; 4,294,967,295)으로 40억이 넘어가기 때문에 long으로 사용해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;1부터 더해야 하기 때문에 idx를 1로 시작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;200을 예로 들었을 때, 아래의 코드는 sum = 210, idx = 21인 상태에서 if문에 걸리게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;idx++이 된 부분에 대해서 한번 빼주고, sum이 초과되는 부분에서 한번 더 빼준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;설명으로 하니 복잡한데 반복문 내에 idx와 sum을 찍어보면 아래와 같이 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678883116266&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//idx sum
1 1
2 3
3 6
...
19 190
20 210
나가!
19&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;후위연산자로 증가한 값을 하나 줄여주고, 반복문 내에서 sum이 초과한 이전의 숫자를 사용하기 위해 한번 더 빼준다.&lt;/span&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;따라서 idx를 -2 해주게 되는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;처음에 이것을 잡는데 시간이 오래 걸렸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;그 외의 반례로는 input 1, output 1을 확인하기.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1656773517815&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main{

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        long S = Long.parseLong(br.readLine());

        //1부터 계속 더하면서 S가 넘지 않을때까지 반복
        long sum = 0;
        long idx = 1;
        while(true){
        	//System.out.print(idx +&quot; &quot;);
            sum += idx++;
            //System.out.println(sum);
            if(sum &amp;gt; S){
                //System.out.println(&quot;나가!&quot;);
                idx-=2;
                break;
            }
        }
        System.out.println(idx);
    }
}&lt;/code&gt;&lt;/pre&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;</description>
      <category>Problem Solving/BOJ</category>
      <category>BOJ</category>
      <category>그리디</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/48</guid>
      <comments>https://nnindd.tistory.com/48#entry48comment</comments>
      <pubDate>Wed, 15 Mar 2023 21:29:16 +0900</pubDate>
    </item>
    <item>
      <title>[Openvidu] 공식 문서 공부</title>
      <link>https://nnindd.tistory.com/47</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.openvidu.io/en/2.25.0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.openvidu.io/en/2.25.0/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1676873854525&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;OpenVidu Docs&quot; data-og-description=&quot;From here you can search these documents. Enter your search terms below.&quot; data-og-host=&quot;docs.openvidu.io&quot; data-og-source-url=&quot;https://docs.openvidu.io/en/2.25.0/&quot; data-og-url=&quot;https://docs.openvidu.io/en/2.25.0/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cHZIoT/hyRHuAFb51/O8GGlwKGuMsLbR5xVxQZJK/img.png?width=1120&amp;amp;height=720&amp;amp;face=0_0_1120_720,https://scrap.kakaocdn.net/dn/jxV14/hyRGacJQy8/SqLVFCULDbKCgytlG0DBa0/img.png?width=1120&amp;amp;height=720&amp;amp;face=0_0_1120_720&quot;&gt;&lt;a href=&quot;https://docs.openvidu.io/en/2.25.0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.openvidu.io/en/2.25.0/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cHZIoT/hyRHuAFb51/O8GGlwKGuMsLbR5xVxQZJK/img.png?width=1120&amp;amp;height=720&amp;amp;face=0_0_1120_720,https://scrap.kakaocdn.net/dn/jxV14/hyRGacJQy8/SqLVFCULDbKCgytlG0DBa0/img.png?width=1120&amp;amp;height=720&amp;amp;face=0_0_1120_720');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;OpenVidu Docs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;From here you can search these documents. Enter your search terms below.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.openvidu.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 공식 문서를 보고 정리한 내용&lt;/p&gt;
&lt;h1&gt;간단 정리&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Openvidu deployment - Docker&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실시간 오디오 및 비디오 스트리밍에 필요한 모든 인프라 제공&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Application server - Backend&lt;/h3&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;h3 data-ke-size=&quot;size23&quot;&gt;Openvidu browser - Frontend&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈비두 개체 가져오고 setState로 세션 속성 초기화&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;세션 나가기&lt;/p&gt;
&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;브라우저가 세션 참여하려고 서버한테 토큰 달라고 요청&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;브라우저는 오픈비두로 세션 참가&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;h1&gt;구조&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VggKD/btrZ660q1LT/AYx6W6wt3B9PFV0jCiP1EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VggKD/btrZ660q1LT/AYx6W6wt3B9PFV0jCiP1EK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VggKD/btrZ660q1LT/AYx6W6wt3B9PFV0jCiP1EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVggKD%2FbtrZ660q1LT%2FAYx6W6wt3B9PFV0jCiP1EK%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;712&quot; height=&quot;731&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;OpenVidu deployment&lt;/b&gt; : 내부 측면이 중요하지 않은 블랙박스. 가져다쓰세요~&lt;/li&gt;
&lt;li&gt;&lt;b&gt;server application&lt;/b&gt; : Rest API endpoints 호출 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;client application&lt;/b&gt; : 웹 브라우저, 데스크톱 애플리케이션에서 실행. openvidu-browser.js SDK사용해서 OpenVidu deployment와 통신, 세션 연결, 미디어스트림 게시 및 구독, 클라이언트측에서 화상통화 관리 등&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Workflow&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciRkCM/btrZ0Kw5WV1/9QhIqO0sjUy3JQDoJ812V1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciRkCM/btrZ0Kw5WV1/9QhIqO0sjUy3JQDoJ812V1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciRkCM/btrZ0Kw5WV1/9QhIqO0sjUy3JQDoJ812V1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciRkCM%2FbtrZ0Kw5WV1%2F9QhIqO0sjUy3JQDoJ812V1%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;712&quot; height=&quot;731&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;애플리케이션 서버에서 세션 초기화&lt;/li&gt;
&lt;li&gt;애플리케이션 서버에서 세션의 연결 생성. 참가자가 있을 만큼 연결 만들어야 함. 토큰은 세션에 대해 단일 접근&lt;/li&gt;
&lt;li&gt;세션에 연결할 수 있게 클라이언트에게 토큰 전달&lt;/li&gt;
&lt;li&gt;클라이언트는 토큰 사용하여 세션에 연결(openvidu-browser.js). 성공적으로 되면 참가자로 간주.&lt;/li&gt;
&lt;li&gt;세션에 연결되면, 참가자는 스트림 게시 가능(openvidu-browser.js). 모든 참가자들은 subscribe 기회 있음&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;용어 정리&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;온프레미스 :&lt;/b&gt;&amp;nbsp;기업이 자체 시설에서 보유하고 직접 유지 관리하는 프라이빗 데이터 센터&lt;/li&gt;
&lt;li&gt;&lt;b&gt;endpoint :&lt;/b&gt;&amp;nbsp;API는 두 어플리케이션이 상호작용 할 수 있게 하는 것이라면 Endpoint는 API가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Session(세션) :&lt;/b&gt; 참가자가 연결하여 오디오/비디오 스트림을 보내고 받을 수 있는 가상 공간. 동일한 세션 연결된 참가자만 서로 보고 들을 수 있음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;b&gt;Connection(연결) :&lt;/b&gt;&lt;/b&gt; 각 세션의 참가자. 세션에 연결하여면 서버에서 초기화하고 해당 토큰을 클라이언트에 전달해야 함.&lt;b&gt;&lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Token(토큰) : 참가자에게 세션에 대한 액세스 권한. 서버에서 연결을 생성해야 클라이언트에게 토큰을 전달 가능&lt;/li&gt;
&lt;li&gt;Stream(스트림) : 세션으로 흐르는 미디어 스트림&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bls9gv/btrZQdNIQTd/MWYMGjUGY7768cBPkDoYn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bls9gv/btrZQdNIQTd/MWYMGjUGY7768cBPkDoYn0/img.png&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;480&quot; data-is-animation=&quot;false&quot; width=&quot;346&quot; height=&quot;310&quot; data-widthpercent=&quot;48.05&quot; style=&quot;width: 47.4897%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bls9gv/btrZQdNIQTd/MWYMGjUGY7768cBPkDoYn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbls9gv%2FbtrZQdNIQTd%2FMWYMGjUGY7768cBPkDoYn0%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;535&quot; height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ldCT1/btrZQcVwkL8/cos06nr7S7Kkk64Rdxe3Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ldCT1/btrZQcVwkL8/cos06nr7S7Kkk64Rdxe3Mk/img.png&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;468&quot; data-is-animation=&quot;false&quot; width=&quot;383&quot; height=&quot;318&quot; style=&quot;width: 51.3476%;&quot; data-widthpercent=&quot;51.95&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ldCT1/btrZQcVwkL8/cos06nr7S7Kkk64Rdxe3Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FldCT1%2FbtrZQcVwkL8%2Fcos06nr7S7Kkk64Rdxe3Mk%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;564&quot; height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;Openvidu - Client&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Ready-to-use component
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어플리케이션에 바로 적용&lt;/li&gt;
&lt;li&gt;몇줄의 코드로 화상 회의&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Full control of the UI&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트 SDK 사용하여 데스크톱 애플리케이션에서 처음부터 사용&lt;/li&gt;
&lt;li&gt;원하는대로 UI 구축&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Openvidu - Server&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션을 생성하고 연결하기 위해서는 클라이언트가 연결하기 전에 오픈비두배포와 연결을 주고받아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바와 Node SDK가 있음. 백엔드에서 REST API 사용해서도 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서 오픈비두배포에 도달하려면 오픈비두배포 URL OPENVIDU_URL과 오픈비두암호 OPENVIDU_SECRET가 필요함&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 세션 초기화&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션 초기화. 동일 세션에 연결된 참가자는 스트림을 주고받을 수 있음&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;OpenVidu openvidu = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
SessionProperties properties = new SessionProperties.Builder().build();
Session session = openVidu.createSession(properties);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 세션 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 세션에 대한 연결 생성. 각 참가자는 토큰 사용하여 하나의 연결 사용해서 연결됨&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;ConnectionProperties connectionProperties = new ConnectionProperties.Builder()
    .role(OpenViduRole.PUBLISHER)
    .data(&quot;Alice&quot;)
    .build();
Connection connection = session.createConnection(connectionProperties);
String token = connection.getToken(); // Send this string to the client side
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자바 기본 코드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 11 / Maven&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만! Gradle로 사용할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기본 제공 Rest endpoints&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 세션 초기화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP METHOD POST&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;URL&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://localhost:5000/api/sessions&quot;&gt;https://localhost:5000/api/sessions&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REQUEST BODY&lt;/td&gt;
&lt;td&gt;Same request body as the REST API operation&amp;nbsp;&lt;a href=&quot;https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-session&quot;&gt;https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-session&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200 OK RETURN VALUE&lt;/td&gt;
&lt;td&gt;A string with the Session identifier.For example:&amp;nbsp;&quot;ses_JM9v0nfD1l&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 세션 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP METHOD POST&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;URL&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://localhost:5000/api/sessions/SESSION_ID/connections&quot;&gt;https://localhost:5000/api/sessions/SESSION_ID/connections&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REQUEST BODY&lt;/td&gt;
&lt;td&gt;Same request body as the REST API operation&amp;nbsp;&lt;a href=&quot;https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-connection&quot;&gt;https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-connection&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200 OK RETURN VALUE&lt;/td&gt;
&lt;td&gt;A string with the Connection's token.For example:&amp;nbsp;&quot;wss://localhost:4443?sessionId=ses_JM9v0nfD1l&amp;amp;token=tok_MIYGGzuDQb8Xf1Qd&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&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;근데! 서버에서 사용자 인증 없으면 아래 6가지 사용 가능&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본 인증&lt;/li&gt;
&lt;li&gt;쿠키 기반 인증&lt;/li&gt;
&lt;li&gt;토큰 기반 인증&lt;/li&gt;
&lt;li&gt;OAuth 2.0&lt;/li&gt;
&lt;li&gt;OpenID Connect&lt;/li&gt;
&lt;li&gt;SAML&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;openvidu-browser.js&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;세션 초기화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Openvidu 개체를 가져오고 이를 사용하여 세션 개체를 초기화함&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;OV = new OpenVidu();
session = OV.initSession();
session.on(&quot;streamCreated&quot;, function (event) {
    session.subscribe(event.stream, &quot;subscriber&quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;토큰 받기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션에 참여할 준비가 됨. 접근하려면 토큰이 필요함. 서버에게 토큰 달라고 요청. 서버는 openvidu에게 토큰 달라고 요청. 서버가 토큰을 클라이언트에게 줌&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;var APPLICATION_SERVER_URL = &quot;&amp;lt;http://localhost:5000/&amp;gt;&quot;;

function getToken(mySessionId) {
    return createSession(mySessionId).then(sessionId =&amp;gt; createToken(sessionId));
}

function createSession(sessionId) {
    return new Promise((resolve, reject) =&amp;gt; {
        $.ajax({
            type: &quot;POST&quot;,
            url: APPLICATION_SERVER_URL + &quot;api/sessions&quot;,
            data: JSON.stringify({ customSessionId: sessionId }),
            headers: { &quot;Content-Type&quot;: &quot;application/json&quot; },
            success: response =&amp;gt; resolve(response), // The sessionId
            error: (error) =&amp;gt; reject(error)
        });
    });
}

function createToken(sessionId) {
    return new Promise((resolve, reject) =&amp;gt; {
        $.ajax({
            type: 'POST',
            url: APPLICATION_SERVER_URL + 'api/sessions/' + sessionId + '/connections',
            data: JSON.stringify({}),
            headers: { &quot;Content-Type&quot;: &quot;application/json&quot; },
            success: (response) =&amp;gt; resolve(response), // The token
            error: (error) =&amp;gt; reject(error)
        });
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;getToken(mySessionId)에서 createSession을 실행하고 거기서 얻어온 sessionId를 가지고 createToken(sessionId) 실행. 생성된 토큰을 받아온다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;토큰 사용하여 세션에 연결&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;getToken(mySessionId).then(token =&amp;gt; {

    session.connect(token)
        .then(() =&amp;gt; {
            document.getElementById(&quot;session-header&quot;).innerText = mySessionId;
            document.getElementById(&quot;join&quot;).style.display = &quot;none&quot;;
            document.getElementById(&quot;session&quot;).style.display = &quot;block&quot;;

            var publisher = OV.initPublisher(&quot;publisher&quot;);
            session.publish(publisher);
        })
        .catch(error =&amp;gt; {
            console.log(&quot;There was an error connecting to the session:&quot;, error.code, error.message);
        });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;session.connect : 오픈비두 서버에서 최근 받은 토큰을 넘겨주면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결이 성공되면 view를 활성 비디오 세션으로 설정. 그리고 웹캠 볼 수 있게 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;publisher로 만든다. 초기화는 .initPublisher. 비디오란은 보이게 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;session.publish(publisher)로 게시&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;세션 나가기&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function leaveSession() {
    session.disconnect();
    document.getElementById(&quot;join&quot;).style.display = &quot;block&quot;;
    document.getElementById(&quot;session&quot;).style.display = &quot;none&quot;;
}

window.onbeforeunload = function () {
    if (session) session.disconnect();
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 세션을 나가길 원할때 session.disconnect 사용하게 함. 나가면 join 버튼 활성화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;window.onbeforeunload : event를 사용하여 페이지가 언로드되기 전에 메서드가 호출되는지 확인&lt;/p&gt;
&lt;h1&gt;React의 경우&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.openvidu.io/en/stable/tutorials/openvidu-react/&quot;&gt;openvidu-react - OpenVidu Docs&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Project</category>
      <category>openvidu</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/47</guid>
      <comments>https://nnindd.tistory.com/47#entry47comment</comments>
      <pubDate>Mon, 20 Feb 2023 15:18:06 +0900</pubDate>
    </item>
    <item>
      <title>[Git] 자주 사용하는 Git 명령어</title>
      <link>https://nnindd.tistory.com/46</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;code&gt;git branch 브랜치명&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;브랜치 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;브랜치 전환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;code&gt;git checkout 브랜치명&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;원격 저장소 연결 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;code&gt;git remote -v&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;원격 저장소에 branch 올리기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;code&gt;git push origin 브랜치명&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;브랜치 삭제&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;code&gt;git branch -d 브랜치명&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치 삭제 에러&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;error: The branch 'feature/docs' is not fully merged. If you are sure you want to delete it, run 'git branch -D feature/docs'.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 에러는 브랜치가 merge 되기 전에 삭제될 수 없다는 것이니 원격에 push가 됐다면 아래 명령어로 삭제해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;git branch -D 브랜치명&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 브랜치 clone&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;git clone -b 브랜치명 --single-branch 저장소URL&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 브랜치 pull&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;git pull origin 브랜치명&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;code&gt;git reset --hard&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;code&gt;git checkout -- 파일명.확장자&lt;/code&gt;&lt;/p&gt;</description>
      <category>Project</category>
      <category>git</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/46</guid>
      <comments>https://nnindd.tistory.com/46#entry46comment</comments>
      <pubDate>Mon, 20 Feb 2023 15:13:00 +0900</pubDate>
    </item>
    <item>
      <title>[Git] fork 한 repository 업데이트 하기</title>
      <link>https://nnindd.tistory.com/45</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;포크한 저장소 로컬에 클론&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;$ git clone &amp;lt;주소&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;로컬 저장소로 이동&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;$ cd &amp;lt;레포지토리명&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;리모트 확인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;$ git remote -v&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;원본 레포지토리 리모트 추가&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;$ git remote add upstream &amp;lt;원본레포지토리주소&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;추가된 리모트 저장소 확인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;$ git remote -v&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;리모트 저장소 fetch&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;$ git fetch upstream&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;merge&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;$ git merge upstream/main&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;136&quot; data-origin-height=&quot;27&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxWMTg/btrUKX2IpOs/21P7qTQJZ5uz81Z6zJWtF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxWMTg/btrUKX2IpOs/21P7qTQJZ5uz81Z6zJWtF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxWMTg/btrUKX2IpOs/21P7qTQJZ5uz81Z6zJWtF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxWMTg%2FbtrUKX2IpOs%2F21P7qTQJZ5uz81Z6zJWtF1%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;136&quot; height=&quot;27&quot; data-origin-width=&quot;136&quot; data-origin-height=&quot;27&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 git bash를 사용하였고, 사진의 괄호에 있는 것에 따라 upstream/ 다음에 main이나 master로 써줘야 정상적으로 처리 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분에서 무엇을 입력하라고 창이 바뀌었는데 :wq를 누르고 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;포크 저장소로 push&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;$ git push&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 다음부턴 6번부터 사용하면 된다.&lt;/p&gt;</description>
      <category>Project</category>
      <category>git</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/45</guid>
      <comments>https://nnindd.tistory.com/45#entry45comment</comments>
      <pubDate>Mon, 26 Dec 2022 20:21:24 +0900</pubDate>
    </item>
    <item>
      <title>[백준 Java] 1916 최소비용 구하기</title>
      <link>https://nnindd.tistory.com/44</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1916&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1916&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;접근 방법&lt;/h4&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;다익스트라 메서드에서 거리 테이블을 만들어준다. 초기는 무한값으로 설정해준다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1671436298450&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main_1916_최소비용구하기 {

	static int N, M;
	static final int INF = Integer.MAX_VALUE;
	static ArrayList&amp;lt;ArrayList&amp;lt;Node&amp;gt;&amp;gt; list;

	static class Node implements Comparable&amp;lt;Node&amp;gt; {
		int idx, cost; // 연결도시, 가중치

		public Node(int idx, int cost) {
			this.idx = idx;
			this.cost = cost;
		}

		@Override
		public int compareTo(Node o) { // 가중치 오름차순 정렬
			return this.cost - o.cost;
		}

	}

	private static int dijkstra(int start, int end) {
		int[] dist = new int[N + 1]; // 0번째 버림

		// INF 초기화
		for (int i = 0; i &amp;lt; N + 1; i++) {
			dist[i] = INF;
		}

		// 최단거리 테이블 초기 설정 - 최소 거리 순으로 정렬 위해
		PriorityQueue&amp;lt;Node&amp;gt; pq = new PriorityQueue&amp;lt;&amp;gt;();
		pq.add(new Node(start, 0)); // 초기 거리 넣어줌

		// 시작 거리 0
		dist[start] = 0;

		// dijkstra
		while (!pq.isEmpty()) {
			Node cur = pq.poll();

			// 현재 가중치가 더 크다면 진행 안함
			if (dist[cur.idx] &amp;lt; cur.cost)
				continue;

			// 현재 노드와 연결된 노드 파악
			for (int i = 0; i &amp;lt; list.get(cur.idx).size(); i++) {
				Node next = list.get(cur.idx).get(i); // 연결된 노드를 가져옴

				if (dist[next.idx] &amp;gt; cur.cost + next.cost) { // 거쳐가는 것이 더 비용이 작다면
					dist[next.idx] = cur.cost + next.cost;
					pq.offer(new Node(next.idx, dist[next.idx])); // 갱신된 거리를 큐에 넣어준다.
				}
			}
		}

		return dist[end];
	}

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer tokens;

		N = Integer.parseInt(br.readLine()); // 도시의 개수
		M = Integer.parseInt(br.readLine()); // 버스의 개수

		list = new ArrayList&amp;lt;ArrayList&amp;lt;Node&amp;gt;&amp;gt;();

		for (int i = 0; i &amp;lt; N + 1; i++) { // 0번째 노드 버림
			list.add(new ArrayList&amp;lt;&amp;gt;());
		}

		for (int i = 0; i &amp;lt; M; i++) {
			tokens = new StringTokenizer(br.readLine());

			// 출발 도시, 도착 도시, 버스 비용
			int start = Integer.parseInt(tokens.nextToken());
			int end = Integer.parseInt(tokens.nextToken());
			int cost = Integer.parseInt(tokens.nextToken());

			list.get(start).add(new Node(end, cost)); // 연결 도시 저장
		}

		tokens = new StringTokenizer(br.readLine());
		int S = Integer.parseInt(tokens.nextToken()); // 출발 도시
		int E = Integer.parseInt(tokens.nextToken()); // 도착 도시

		System.out.println(dijkstra(S, E));

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 행렬로 풀었었는데 틀린 답이 나왔다. 백준의 질문 게시판을 살펴보니 인접행렬을 사용했을 경우 중복값에 대한 처리가 어쩌구 써있어서 인접리스트를 사용했다.&lt;/p&gt;</description>
      <category>Problem Solving/BOJ</category>
      <category>백준</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/44</guid>
      <comments>https://nnindd.tistory.com/44#entry44comment</comments>
      <pubDate>Mon, 19 Dec 2022 16:52:03 +0900</pubDate>
    </item>
    <item>
      <title>[알고리즘 정리] 그래프 (Graph)와 Floyd warshall 알고리즘</title>
      <link>https://nnindd.tistory.com/43</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;그래프란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정점과 간선으로 이루어진 자료구조를 말한다. 무슨 소리지? 싶어 그림을 첨부했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;531&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nMLFT/btrT4qDxJ5r/hOt3cjkCq1m3I9Qywaw2V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nMLFT/btrT4qDxJ5r/hOt3cjkCq1m3I9Qywaw2V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nMLFT/btrT4qDxJ5r/hOt3cjkCq1m3I9Qywaw2V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnMLFT%2FbtrT4qDxJ5r%2FhOt3cjkCq1m3I9Qywaw2V0%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;300&quot; height=&quot;339&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;531&quot;/&gt;&lt;/span&gt;&lt;/figure&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정점&lt;/b&gt;(Vertex)은 노드(Node)라고도 하며 그림의 A, B, C ... 와 같은 동그라미를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;간선&lt;/b&gt;(Edge)은 링크(Link)라고도 하며 노드를 이은 선을 말한다. 화살표가 없으면 무뱡향 그래프, 화살표가 있으면 단방향/양방향 그래프가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가중치는 간선에 표시된 숫자이다. 있을수도 없을 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그래프의 특징&lt;/b&gt;&lt;/h3&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그래프 구현&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인접행렬&lt;/li&gt;
&lt;li&gt;인접리스트&lt;/li&gt;
&lt;li&gt;간선리스트&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세가지 방식으로 구현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;인접행렬&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 첨부된 사진으로 예를 들었을 때 인접 행렬로 그래프의 정보를 나타낸다면 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 66.0465%; height: 205px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignCenter&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;A&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;B&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;C&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;D&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;E&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;A&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;B&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;C&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;D&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;E&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;인접리스트&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결된 노드만 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;A&lt;/b&gt; &amp;rarr; B&amp;nbsp;&amp;rarr; D &amp;rarr; E&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;B&lt;/b&gt; &amp;rarr; A &amp;rarr; C &amp;rarr; D&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;C&lt;/b&gt; &amp;rarr; B &amp;rarr; D&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;D&lt;/b&gt; &amp;rarr; A &amp;rarr; B &amp;rarr; C &amp;rarr; E&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;E&lt;/b&gt; &amp;rarr; A &amp;rarr; D&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;단점은 구현 어려움&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 알고리즘을 풀다보면 점점 인접리스트로 구현하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;그래프 알고리즘&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DFS : 출발점과 도착점의 모든 경로를 탐색&lt;/li&gt;
&lt;li&gt;정점의 &lt;b&gt;최단거리 알고리즘&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;단일 출발점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BFS : 가중치가 없음&lt;/li&gt;
&lt;li&gt;Dijkstra : 가중치 있음. 음의 가중치 없음&lt;/li&gt;
&lt;li&gt;Bellman-ford : 가중치 있음. 음의 가중치 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모든 출발점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Floyd warshall&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;DFS&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;BFS&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Dijkstra&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Bellman-ford&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Floyd warshall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;연결 정점 선택 후 끝날때까지 파고 들어가며 탐색&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;연결된 주변 정점 퍼져나가듯 탐색&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;한 정점에서 다른 정점까지의 최소 가중치 탐색&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;(수정중)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;모든 정점에서 각 정점까지의 최소 가중치 탐색&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;자료구조&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;Stack / recursive&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;Queue&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;heap&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;(수정중)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;3중 for문&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;시간복잡도&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3334%;&quot; colspan=&quot;2&quot;&gt;인접행렬 O(V^2)&lt;br /&gt;인접리스트 O(V+E)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;O(V^2)&lt;br /&gt;힙 사용 O(ElogV)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;(수정중)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;O(V^3)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Floyd warshall 알고리즘&lt;/b&gt;&lt;/h3&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRaUeW/btrTYCd34lT/EIc4kSV7rUZvivLeDxmdw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRaUeW/btrTYCd34lT/EIc4kSV7rUZvivLeDxmdw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRaUeW/btrTYCd34lT/EIc4kSV7rUZvivLeDxmdw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRaUeW%2FbtrTYCd34lT%2FEIc4kSV7rUZvivLeDxmdw0%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;298&quot; height=&quot;305&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동작 과정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 그래프의 최단 거리 테이블 갱신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. n번째 노드를 거쳐 가는 경우에 대해 테이블 갱신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;그래프의 최단 거리 테이블 갱신&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DXGDD/btrT5a1tmW5/3C7F3LZt5oWoJbBAfkb9k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DXGDD/btrT5a1tmW5/3C7F3LZt5oWoJbBAfkb9k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DXGDD/btrT5a1tmW5/3C7F3LZt5oWoJbBAfkb9k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDXGDD%2FbtrT5a1tmW5%2F3C7F3LZt5oWoJbBAfkb9k0%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;400&quot; height=&quot;228&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;i &amp;rarr; j로 가는 방향에 가중치를 표시해줬고, 갈 수 없는 경우는 무한 값으로 설정했다. 자기 자신으로 가는 경우는 0이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;n번째 노드를 거쳐 가는 경우&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결되어 갈 수 있는 경우에만 갱신해준다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;1번째 노드 A를 거쳐 가는 경우&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1167&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZApMm/btrTT70iCVs/vJdc9BHsghyO6thbdNyTEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZApMm/btrTT70iCVs/vJdc9BHsghyO6thbdNyTEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZApMm/btrTT70iCVs/vJdc9BHsghyO6thbdNyTEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZApMm%2FbtrTT70iCVs%2FvJdc9BHsghyO6thbdNyTEk%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;1167&quot; height=&quot;370&quot; data-origin-width=&quot;1167&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A를 거쳐서 갈 수 있는 경우는 B &amp;rarr; C의 경우만 존재한다. 갱신된 값을 비교하여 테이블을 갱신해준다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0VhGP/btrT2QJF5Dm/ucih9dKiuZHKsFaexLNIJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0VhGP/btrT2QJF5Dm/ucih9dKiuZHKsFaexLNIJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0VhGP/btrT2QJF5Dm/ucih9dKiuZHKsFaexLNIJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0VhGP%2FbtrT2QJF5Dm%2Fucih9dKiuZHKsFaexLNIJk%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;400&quot; height=&quot;227&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;2번째 노드 B를 거쳐 가는 경우&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p6M1s/btrTT678pD3/wrlEwj33ZuKVN1PsGf1eH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p6M1s/btrTT678pD3/wrlEwj33ZuKVN1PsGf1eH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p6M1s/btrTT678pD3/wrlEwj33ZuKVN1PsGf1eH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp6M1s%2FbtrTT678pD3%2FwrlEwj33ZuKVN1PsGf1eH1%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;1172&quot; height=&quot;396&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D&amp;rarr;B&amp;rarr;A&amp;rarr;C의 경우는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 B&amp;rarr;C 경로가 B&amp;rarr;A&amp;rarr;C 인 최단경로로 업데이트됐기 때문에 D&amp;rarr;B&amp;rarr;C 가 아닌&lt;b&gt; D&amp;rarr;B&amp;rarr;A&amp;rarr;C&lt;/b&gt;가 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;540&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xiMdT/btrT2QXgyEE/dsrbktZahjM4l0kyFyVfU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xiMdT/btrT2QXgyEE/dsrbktZahjM4l0kyFyVfU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xiMdT/btrT2QXgyEE/dsrbktZahjM4l0kyFyVfU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxiMdT%2FbtrT2QXgyEE%2FdsrbktZahjM4l0kyFyVfU1%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;400&quot; height=&quot;227&quot; data-origin-width=&quot;540&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;3번째 노드 C를 거쳐 가는 경우&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpGPbH/btrT3pkXjfP/VQTtKqKKlmta98s0h4K0Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpGPbH/btrT3pkXjfP/VQTtKqKKlmta98s0h4K0Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpGPbH/btrT3pkXjfP/VQTtKqKKlmta98s0h4K0Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpGPbH%2FbtrT3pkXjfP%2FVQTtKqKKlmta98s0h4K0Kk%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;1172&quot; height=&quot;396&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 BCD의 경우도 BACD로 갱신된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kydBD/btrT5blQNYN/ggU7tNVii0weG9zUcdzL8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kydBD/btrT5blQNYN/ggU7tNVii0weG9zUcdzL8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kydBD/btrT5blQNYN/ggU7tNVii0weG9zUcdzL8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkydBD%2FbtrT5blQNYN%2FggU7tNVii0weG9zUcdzL8k%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;400&quot; height=&quot;226&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;4번째 노드 D를 거쳐 가는 경우&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkMjbn/btrTVU0DHQv/1D8pOom0AkZ2flSzgdRb51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkMjbn/btrTVU0DHQv/1D8pOom0AkZ2flSzgdRb51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkMjbn/btrTVU0DHQv/1D8pOom0AkZ2flSzgdRb51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkMjbn%2FbtrTVU0DHQv%2F1D8pOom0AkZ2flSzgdRb51%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;1175&quot; height=&quot;560&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CDB를 새로 연결해준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CDB가 갱신되었기 때문에 CDBA의 새 경로를 업데이트해줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AD는 위에서 연결이 새로 갱신되었기 때문에 ACDB로 갱신해줄 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b22xZ1/btrT4rv7aAp/4k8VPg9iaRq51YfBKhGAi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b22xZ1/btrT4rv7aAp/4k8VPg9iaRq51YfBKhGAi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b22xZ1/btrT4rv7aAp/4k8VPg9iaRq51YfBKhGAi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb22xZ1%2FbtrT4rv7aAp%2F4k8VPg9iaRq51YfBKhGAi1%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;400&quot; height=&quot;225&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;의사코드&lt;/h4&gt;
&lt;pre id=&quot;code_1671432951417&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let dist be V &amp;times; V matrix of minimum distances initialized to INFINITY
for each vertex v
  dist[v][v] = 0
for each edge (u, v)
  dist[u][v] = weight(u, v)
 
for k from 0 to |V| &amp;ndash; 1
  for i from 0 to |V| &amp;ndash; 1
    for j from 0 to |V| &amp;ndash; 1
      if (dist[i][k] + dist[k][j]) is less than dist[i][j] then
        dist[i][j] = dist[i][k] + dist[k][j]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기값을 INF로 초기화해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자기 자신에 대해서는 0으로, 간선이 존재하면 가중치로 갱신해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거쳐가는 노드를 k로 두고 노드만큼 반복한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;i는 시작하는 노드, j는 도착하는 노드이고 각각 노드의 수만큼 반복해준다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 현재 i, j의 연결보다 k를 거쳐가는 경우가 더 작다면 갱신해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현은 셀프 ^-^&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;풀어보면 좋은 문제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백준 11404 플로이드 - 골드4&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11404&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11404&lt;/a&gt;&lt;/p&gt;</description>
      <category>CS/Algorithm</category>
      <category>그래프</category>
      <category>알고리즘</category>
      <category>플로이드워셜</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/43</guid>
      <comments>https://nnindd.tistory.com/43#entry43comment</comments>
      <pubDate>Mon, 19 Dec 2022 16:01:25 +0900</pubDate>
    </item>
    <item>
      <title>[SWEA Java] 1949. 등산로 조성</title>
      <link>https://nnindd.tistory.com/42</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;기본 등산로 조성은 dfs로 4방향에서 갈 수 있다면 방문처리 해주고 가는 방식으로 짰는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;산을 깎는 경우를 잘 모르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 N만큼 i,j for문 돌리고 그 안에서 K만큼 반복문 돌려서 다 깎아봤어도 시간 초과가 안 났을 것 같은데 풀다보니 이렇게 풀게 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;❗️현재 높이와 다음 높이를 비교했을 때, 작은 경우와 큰 경우를 따로 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;❗️큰 경우라면 이전에 깎았는지 확인하고 &lt;code&gt;안깎깎 ? 깎 : 안깎&lt;/code&gt;처리를 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;❗️다음 높이가 높을 때 깎는 높이는 현재 높이에서 1만 깎으면 된다. 물론 K만큼 깎았을 때 현재 높이보다 낮아야 한다. 이거 이해하는데 오래 걸렸다&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드&lt;/h4&gt;
&lt;pre id=&quot;code_1669030762068&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package SWEA;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Solution_1949_등산로조성 {

    static int N, K, res;
    static int[][] map;
    static boolean[][] v;
    static int[] dr = {-1, 1, 0, 0}, dc = {0, 0, -1, 1};

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokens;
        StringBuilder sb = new StringBuilder();
        int T = Integer.parseInt(br.readLine());

        for (int tc = 1; tc &amp;lt;= T; tc++) {
            tokens = new StringTokenizer(br.readLine());
            N = Integer.parseInt(tokens.nextToken());
            K = Integer.parseInt(tokens.nextToken());

            map = new int[N][N];
            v = new boolean[N][N];
            int max = 0;

            for (int i = 0; i &amp;lt; N; i++) {
                tokens = new StringTokenizer(br.readLine());
                for (int j = 0; j &amp;lt; N; j++) {
                    map[i][j] = Integer.parseInt(tokens.nextToken());
                    if (max &amp;lt; map[i][j]) max = map[i][j];
                }
            } // end input

            res = 0;
            for (int i = 0; i &amp;lt; N; i++) {
                for (int j = 0; j &amp;lt; N; j++) {
                    if (map[i][j] == max) {
                        dfs(i, j, 1, true);
                    }
                }
            }
            sb.append(&quot;#&quot;).append(tc).append(&quot; &quot;).append(res).append(&quot;\n&quot;);
        } // end test case
        System.out.println(sb);
    }

    private static void dfs(int x, int y, int len, boolean flag) {
        v[x][y] = true;
        for (int d = 0; d &amp;lt; 4; d++) {
            int nx = x + dr[d];
            int ny = y + dc[d];

            // 범위 밖, 방문이면 다음 방향
            if (!isRange(nx, ny) || v[nx][ny])
                continue;

            //다음 높이가 현재 높이보다 작을때
            if (map[nx][ny] &amp;lt; map[x][y]) {
                dfs(nx, ny, len + 1, flag);
            } else {//다음 높이가 현재 높이보다 같거나 크고 깎을 수 있을 때
                if (flag &amp;amp;&amp;amp; map[nx][ny] - K &amp;lt; map[x][y]) {
                    int temp = map[nx][ny];
                    v[nx][ny] = true;
                    map[nx][ny] = map[x][y]-1;
                    dfs(nx, ny, len + 1, false);
                    map[nx][ny] = temp;
                    v[nx][ny] = false;
                    flag = true;
                }
            }
        }
        v[x][y] = false;
        // 더이상 갈 수 없으면 거리 갱신
        res = Math.max(res, len);
    }

    private static boolean isRange(int x, int y) {
        if (x &amp;lt; 0 || y &amp;lt; 0 || x &amp;gt;= N || y &amp;gt;= N)
            return false;
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Problem Solving/SWEA</category>
      <category>SWEA</category>
      <author>민딛</author>
      <guid isPermaLink="true">https://nnindd.tistory.com/42</guid>
      <comments>https://nnindd.tistory.com/42#entry42comment</comments>
      <pubDate>Mon, 21 Nov 2022 20:45:56 +0900</pubDate>
    </item>
  </channel>
</rss>