<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발지식, 관련지식 저장소</title>
    <link>https://ysldev.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 11 Jun 2026 09:09:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>lys4321</managingEditor>
    <item>
      <title>프로그래머스 Lv2 요격 시스템 문제</title>
      <link>https://ysldev.tistory.com/77</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 요격 시스템 문제
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&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;맵은 2차원 배열이며 a나라의 미사일은 x축과 평행하게 날아오고, b나라의 방어미사일은 y축에 평행하게 발사&lt;/li&gt;
&lt;li&gt;방어미사일은 해당 발사지점의 y축에 속한 x축의 모든 미사일을 관통할 수 있으며 한발로 여러 발 제거 가능&lt;/li&gt;
&lt;li&gt;개구간(s, e)으로 표현되는 미사일은 s,e 좌표에선 미사일을 발사하지 못하므로 방어 불가&lt;/li&gt;
&lt;li&gt;요격 미사일은 실수 x 축에서도 발사가 가능&lt;/li&gt;
&lt;li&gt;배열 내 요소의 최대값은 1억이 최대이므로 int는 사용가능&lt;/li&gt;
&lt;li&gt;길이 또한 5만이 최대이므로 int사용 가능&lt;/li&gt;
&lt;li&gt;예시 그림을 보니 이미 관통한 미사일 경로는 다른 미사일 경로 관통 시, 같이 관통되는 일이 있으면 안됨&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;해당 문제의 난이도 상승 원인&lt;/li&gt;
&lt;li&gt;해당 문제를 해결한 방법&lt;/li&gt;
&lt;li&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;또한 경우의 수 + 최소값 구하기 문제류 이므로 DFS와 BFS가 생각났으나 BFS는 최단 거리에서 적용이 가능하기 때문에 DFS를 사용하기로 결정&lt;/li&gt;
&lt;li&gt;처음 계획은 먼저 타겟배열을 받고 이 배열을 [0]를 기준으로 오름차순 배열 후 DFS를 돌리는 것으로 잡음&lt;/li&gt;
&lt;li&gt;dfs 식으로 작성 후 테스트케이스 완료까지 되는 것을 확인한 후에 코드 테스트를 실행하니 전체 경우중 2가지를 제외하고 전부 시간초과가 발생하여 문제점 분석을 시작&lt;/li&gt;
&lt;li&gt;분석 후 문제점을 확인하니 DFS 쪽에 있었고 DFS가 아닌 Greedy 방식을 사용해야했음을 알게 되었다.원래 DFS를 사용하려한 이유는 이 문제가 완전 탐색문제라고 판단하여 시간을 기준으로 정렬 후 처리하려고 했는데 오히려 이 문제는 시간을 기준으로 정렬하고 해당 시간 내에서 최적의 선택을 해야하기 때문에 Greedy방식이었던 것이다&lt;/li&gt;
&lt;li&gt;DFS를 사용하지 않은 1번 전체순환을 이용한 Greedy 방식으로 변경 후 코드 테스트를 해보았고 아까보단 2개 더 많은 항목을 정답으로 하였으나 그럼에도 오류가 발생하여 다시 분석&lt;/li&gt;
&lt;li&gt;디버그 모드 실시간 분석하면서 확인해보니 순환문 내에서 내가 의도한 내용인 시작범위는 큰 값으로, 종료범위 적운 겂으로 설정하는 것과는 다르게 코드가 작동하는 부분이 있어 해당 부분 수정후 다시 코드 제출ㅇ하니 정답처리 됨&lt;/li&gt;
&lt;/ol&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;DFS를 쓸 상황과 Greedy를 쓸 상황을 판단하는 것&lt;/li&gt;
&lt;li&gt;들어온 데이터를 전처리해야하는 지 말아야하는 지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774242184437&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class Lv2InterceptSystem {
    public static void main(String[] args){
        int[][] targets = {
                {4, 5}, {4, 8}, {10, 14}, {11, 13}, {5, 12}, {3, 7}, {1, 4}
        };
        solution(targets);
    }

    public static boolean isOverLapCheck(int[] a, int[] b){
        //a1&amp;lt;=b2 &amp;amp;&amp;amp; b1 &amp;lt;= a2
        return a[0] &amp;lt; b[1] &amp;amp;&amp;amp; b[0] &amp;lt; a[1];
    }

    public static int solution(int[][] targets){
        Arrays.sort(targets, (a, b) -&amp;gt; Integer.compare(a[1], b[1]));

        for(int[] t: targets) System.out.println(t[0] + &quot;, &quot; + t[1]);
        System.out.println(&quot;-------------------------&quot;);

        int answer = 0;
        int[] compareBase = null;

        for(int i = 0; i &amp;lt; targets.length; i++){
            if(compareBase == null){
                compareBase = new int[]{targets[i][0], targets[i][1]};
                answer++;
                continue;
            }

            if(isOverLapCheck(compareBase, targets[i])){
                compareBase[0] = Math.max(compareBase[0], targets[i][0]);
                compareBase[1] = Math.min(compareBase[1], targets[i][1]);
            }
            else{
                compareBase = new int[]{targets[i][0], targets[i][1]};
                answer++;
            }
        }

        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래머스 코딩 테스트 문제/lv2</category>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/77</guid>
      <comments>https://ysldev.tistory.com/77#entry77comment</comments>
      <pubDate>Mon, 23 Mar 2026 14:03:17 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 N-Queen 문제</title>
      <link>https://ysldev.tistory.com/76</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 N-Queen 문제
&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;가로, 세로 길이가 n(n*n)인 맵이 존재&lt;/li&gt;
&lt;li&gt;이 맵에 n개의 퀸을 인접하지 않은 상태로 배치해야함&lt;/li&gt;
&lt;li&gt;퀸은 가로, 세로, 대각선 이동이 가능&lt;/li&gt;
&lt;li&gt;n은 12 이하&lt;/li&gt;
&lt;li&gt;n 당 n개의 배치자리를 얻음&lt;/li&gt;
&lt;li&gt;모든 경우의 수에서 특정 상황만 카운팅? DFS인가&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;이전 row들에 대한 대각선에서의 퀸 존재확인하는 반복문이 복잡해서 어려움&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;li&gt;해당 문제를 해결였던 과정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;처음에는 이중 순환문으로 해결하려고 코드 작성 중 해당 문제가 이전에 풀었던 DFS 알고리즘을 사용하는 문제같다는 생각이 들어 DFS 방식으로 해결&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;DFS 사용하기&lt;/li&gt;
&lt;li&gt;대각선 상태 확인하기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774242083158&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Lv2NQueen {
    public static void main(String[] args){
        solution(4);
    }

    static boolean[][] map;
    static int answer;

    public static boolean isValid(int n, int row, int col){
        // 세로체크
        for(int i = row - 1; i &amp;gt;= 0; i--) if(map[i][col]) return false;
        // 좌상체크
        for(int i = 1; (row - i &amp;gt;= 0 &amp;amp;&amp;amp; col - i &amp;gt;= 0); i++) if(map[row - i][col - i]) return false;
        // 우상체크
        for(int i = 1; (row - i &amp;gt;= 0 &amp;amp;&amp;amp; col + i &amp;lt; n); i++) if(map[row - i][col + i]) return false;

        return true;
    }

    public static void dfs(int n, int row){
        if(row == n){
            answer++;
            return;
        }

        for(int i = 0; i &amp;lt; n; i++){
            if(isValid(n, row, i)){
                map[row][i] = true;
                dfs(n, row + 1);
                map[row][i] = false;
            }
        }

    }

    public static int solution(int n){
        map = new boolean[n][n];
        answer = 0;

        dfs(n, 0);
        System.out.println(answer);
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래머스 코딩 테스트 문제/lv2</category>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/76</guid>
      <comments>https://ysldev.tistory.com/76#entry76comment</comments>
      <pubDate>Mon, 23 Mar 2026 14:02:13 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 두 원 사이의 정수 쌍 문제</title>
      <link>https://ysldev.tistory.com/75</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 두 원 사이의 정수 쌍 문제
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문제를 읽고 난 후의 분석
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;N의 반지름은 길이가 N인 사각형의 길이보다 작고 N-1인 사각형보다는 길이가 길다.&lt;/li&gt;
&lt;li&gt;r2의 y축에 해당하는 4개의 정수개수를 제외하고 r1의 길이를 가지는 4각형에 속하는 정수를 구한 후 + 4를 해야할 것 같다.&lt;/li&gt;
&lt;li&gt;한 부분의 정수 분포 개수만 구하고 * 4를 해도 개수가 구해질 것 같다.&lt;/li&gt;
&lt;li&gt;위의 생각을 정리하면 이 문제는 일종의 팩토리얼을 구하는 문제외 비슷하다고 생각된다 그 이유는 r2의 길이부분은 4개 + 그 외 작은 사각형으로 생각되며 이 '그 외 작은 사각형 부분 중' 대각선을 나타내는 반지름이 r2의 길이보다 짧을 수 있어 또 다시 4개 + 그 외 작은 사각형으로 나눠지고 최종적으론 r1의 사각형이 나오기 때문이다.&lt;/li&gt;
&lt;li&gt;예시에는 개수가 얼마 없지만 제한사항에 백만개 이하길이까지 가능하다 해서 효율성도 고려해 문제를 풀어야한다.&lt;/li&gt;
&lt;/ol&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;li&gt;해당 문제를 해결한 방법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0,0을 중심으로 가지는 원의 특성을 이용해 1부분의 대한 개수만 구하여 최종적으로 * 4하여 값을 구함&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;처음 에는 값이 1씩 커지면 점이 +2개씩늘어나는 것으로 분석하여 '2n - 3' 이라는 식으로 계산하였지만 테스크케이스로 검사 시 계속 오류로 나와 재분석을 실시&lt;/li&gt;
&lt;li&gt;검색 및 재분석 중 이 문제는 이산수학을 이용한 방법을 사용하여 반지름 범위 내의 점의 개수를 구해야하는 것을 알게됨&lt;/li&gt;
&lt;li&gt;또한 '2n - 3' 공식을 사용하는게 아닌 피타고라스 정리 공식을 사용하여 반지름제곱 - x/y축의 제곱을 하여 나온 값의 제곱급의 차이를 이용해 점의 개수를 구해야 한다는 것을 알게 됨&lt;/li&gt;
&lt;li&gt;또한 이 문제는 r2의 범위에서 r1의 범위에 해당하는 부분의 차를 구하므로 '-'가 되지 않도록 r2분의 범위가 r1의 범위와 같거나 클 때만 빼지도록 하여 음수가 나오는 것을 방지&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;li&gt;소수점 정리&lt;/li&gt;
&lt;li&gt;특이 케이스 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774242018099&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class LvTwoCirclePoint {
    public static void main(String[] args){
        solution(3, 3);
    }

    public static long solution(int r1, int r2) {
        long answer = 0;

        for(long i = 1; i &amp;lt;= r2; i++){
            long maxPoint = (long)Math.sqrt(
                    (long)r2 * r2 - i * i
            );
            long minPoint = (long)Math.ceil(
                    Math.sqrt(
                            Math.max(0, (long)r1 * r1 - i * i)
                    )
            );
            if(maxPoint &amp;gt;= minPoint) answer += maxPoint - minPoint + 1;
        }
        return answer * 4;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래머스 코딩 테스트 문제/lv2</category>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/75</guid>
      <comments>https://ysldev.tistory.com/75#entry75comment</comments>
      <pubDate>Mon, 23 Mar 2026 14:00:31 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 숫자 블록 문제</title>
      <link>https://ysldev.tistory.com/74</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 숫자블록 문제
&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;/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;약 10억이라는 번호가 존재&lt;/li&gt;
&lt;li&gt;내가 문제의 지문을 놓침&lt;/li&gt;
&lt;li&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;최대 블럭 번호인 10,000,000를 이용한 제한점을 두어 이를 만족할 때만 값을 반환하도록 + 만약 소수라면 1을 반환하도록 기능을 작성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;해당 문제를 해결였던 과정
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;숫자들의 최소 공배수에 대한 규칙이 있을 것 같단 예상이 들어 1 ~ 200 까지의 각 자리수에 대한 최대 공약수 테이블을 만들어 비교&lt;/li&gt;
&lt;li&gt;테이블 생성 후 짝수번류는 (해당 짝수 % 2) + (해당 짝수를 10을 몫으로 나눈 후 값) * 5라는 규칙을 가진다는 것을 확인하였고 홀수는 일정한 규칙이 발견되지 않음&lt;/li&gt;
&lt;li&gt;그래서 홀수에 대한 다른 방법을 찾으려는 중 n 을 루트화 후(==sqrt) 나온 수를 체크하여 그것보다 작은 홀수들을 오름차순으로 정렬하여 체크해야 한다는 것을 확인&lt;/li&gt;
&lt;li&gt;위에서 분석한 내용을 기반으로 코드 작성 후 코드 제출로 테스트 해보았으나 정확성에선 1개 오류 + 효율성 시간초과로 에러&lt;/li&gt;
&lt;li&gt;무언가 놓친게 있나 문제를 다시 확인하니 추가 제한사항 발견(블럭 번호의 최대치는 10,000,000)하였고 내코드 에선 최대 500,000,000의 블럭번호까지 존재하여 정확성에서 오류가 발생하였던 것&lt;/li&gt;
&lt;li&gt;또한 효율성이 계속 오류가 나던 원인도 이와 연관되어 계속 실패로 뜨고 있었음&lt;/li&gt;
&lt;li&gt;최대 블럭번호를 10,000,000까지 제한하도록하는 조건을 걸고 (target / i)를 했을 때 처음으로 10,000,000이하가 되는 경우 해당 i 값을 반환하도록 코드 수정하여 효율성도 통과됨을 확인&lt;/li&gt;
&lt;/ol&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;무조건 나눴을 때 나머지가 0인 것이 정답이 아닌, 10,000,000 이하라는 조건을 만족하면서 효율성까지 고려한 코드 설계가 중요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774241939199&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; import javax.xml.stream.events.StartDocument;
import java.util.concurrent.LinkedTransferQueue;

public class Lv2NumBlock {
    public static void main(String[] args){
        solution(1, 10);
    }

    // 1000000000
    // 10000000

    public static int gcd(long target){
        if(target == 1) return 0;
        int returnVal = 1;

        for(int i = 2; i * i &amp;lt;= target; i++){
            if(target % i == 0){
                if(target / i &amp;lt;= 10000000){
                    return (int)(target / i);
                }
                returnVal = i;
            }
        }

        return returnVal;
    }

    public static int[] solution(long begin, long end){
        int[] table = new int[(int)(end - begin + 1)];

        for(int i = (int)begin; i &amp;lt;= (int)end; i++){
            int idx = (int)(i - begin);
            table[idx] = gcd(i);
        }

        return table;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래머스 코딩 테스트 문제/lv2</category>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/74</guid>
      <comments>https://ysldev.tistory.com/74#entry74comment</comments>
      <pubDate>Mon, 23 Mar 2026 13:59:12 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 조이스틱 문제</title>
      <link>https://ysldev.tistory.com/73</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 조이스틱 문제
&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;조이스틱(4방향)으로 알파벳 이름 완성하기&lt;/li&gt;
&lt;li&gt;초기화 상태는 세글자면 'AAA', 네글자면 'AAAA'&lt;/li&gt;
&lt;li&gt;name이 주어질 때 이름에 대하려 조작횟수의 최솟값 구하기가 목표&lt;/li&gt;
&lt;li&gt;최솟값? 최단거리? 를 구하기 위해 뭘 써야하나&lt;/li&gt;
&lt;li&gt;일단 조이스틱은 dx, dy를 활용한 방법같고&lt;/li&gt;
&lt;li&gt;범위 초과 시 처리는 있고&lt;/li&gt;
&lt;li&gt;뭔가 알파벳을 X 축, 글자위치를 Y로 본다면 이건 DFS 계열 같다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;해당 문제의 난이도 상승 원인&lt;/li&gt;
&lt;li&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;처음엔 BFS로 생각하고 BFS에 필요한 기본 재로코드를 타이핑하고 있었는데 문득 같은 단어를 치려고 해도앞으로 전진하면서 찾는 것보다 뒤로 후진하면서 찾는경우가 더 빠를 수 있다고 생각하여 BFS 가 아닌 , 이분 탐색? 에 가까운 경우로 보인거 같다&lt;/li&gt;
&lt;li&gt;그래서 알파벳 A, Z 를 기준으로 각각 0, 25로 정하고&lt;/li&gt;
&lt;li&gt;{대상문자 - A, Z - 대상문자 + 1}식을 사용해 알파벳 이동에 대한 최소거리를 계산해냈으나 테스트케이스를 실행하니 조금씩 값이 다른것을 확인&lt;/li&gt;
&lt;li&gt;그래서 놓친 것이 있나 문제 지문을 다시 살펴보니 y축 또한 이와 비슷하게 처리해야 함을 인지&lt;/li&gt;
&lt;li&gt;y구간 중 가장 긴 연속된 A 구간이 있다면 그것을 피하는게 최소 거리라고 생각되어 매 순환마다 다음 인덱스가 A 구간인지 확인하며 계산 후 정-&amp;gt;역, 역-&amp;gt;정 길이를 구한 다음 둘 중 최소값을 구함 그리고 추가로 문자열 길이 - 1 과 비교하여 최솟값을 구해서 갱신시킴&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;continue는 건너뛰기지 방문 자체는 해버림&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;가장 긴 A문자열을 체크해야하므로 정-&amp;gt;역, 역-정 전체 길이를 구하고 최솟값을 판단&lt;/li&gt;
&lt;li&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;//전체 ------------------------------
//기준 ---------|~~~~~|..............
//다음 ---------------|++++++++++|...  
// 정방향 과 역방향 은 어차피 NL -1 길이를 가지므로 묶임  
// 정방향 + 역방향  
// ((i * 2) + (전체 - 다음))
// 역방향 + 정방향  
// (((전체 - 다음) * 2) + i)&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774241846182&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.List;

public class Lv2JoyStick {
    public static void main(String[] args){
        String name = &quot;JEROEN&quot;;

        System.out.println(solution(name));
    }

    public static int solution(String name) {
        final int START = 'A'; // 65번이다
        final int END = 'Z'; // 90번이다
        final int NL = name.length(); // 문자열 마지막 인덱스

        //전체 ------------------------------
        //다음 ---------------|++++++++++|
        //기준 ---------|~~~~~|

        // 정방향 과 역방향 은 어차피 NL -1 길이를 가지므로 묶임
        // 정방향 + 역방향
        // ((i * 2) + (전체 - 다음)) % 전체
        // 역방향 + 정방향
        // (((전체 - 다음) * 2) + i) % 전체

        int x = 0;
        int y = NL - 1;
        for(int i = 0; i &amp;lt; NL; i++){
            int[] alpahDistArr = {name.charAt(i) - START, END - name.charAt(i) + 1};
            x += Math.min(alpahDistArr[0], alpahDistArr[1]);

            // 0은 초기 위치므로 계산에서 제외됨
            // next는 'A'의 마지막을 나타내는게 아니라 'A'가 아닌 다음 요소 인덱스
            int next = i + 1;
            while(next &amp;lt; NL &amp;amp;&amp;amp; name.charAt(next) == 'A') next++;

            // 배열 내 각각의 수식은 정-&amp;gt;역, 역-&amp;gt;정에 대한 전체 이동길이를 나타내며
            // 연속된 A 구간 중 가장 긴 구간이 있을 때 짧아지는 것으로 생각된다
            // 그러므로 매 순환마다 최솟값을 체크하며 갱신해야한다.

            int[] cursorDistArr = {(i * 2) + (NL - next), (NL - next) * 2 + i};
            int compareVal = Math.min(cursorDistArr[0], cursorDistArr[1]);
            y = Math.min(y, compareVal);

            System.out.println(&quot;x :&quot; + alpahDistArr[0] + &quot;, &quot; + alpahDistArr[1]);
            System.out.println(&quot;y :&quot; + y);
            System.out.println(&quot;----------------------------&quot;);
        }
        return x + y;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/73</guid>
      <comments>https://ysldev.tistory.com/73#entry73comment</comments>
      <pubDate>Mon, 23 Mar 2026 13:58:01 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 조이스틱 문제</title>
      <link>https://ysldev.tistory.com/72</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 조이스틱 문제
&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;조이스틱(4방향)으로 알파벳 이름 완성하기&lt;/li&gt;
&lt;li&gt;초기화 상태는 세글자면 'AAA', 네글자면 'AAAA'&lt;/li&gt;
&lt;li&gt;name이 주어질 때 이름에 대하려 조작횟수의 최솟값 구하기가 목표&lt;/li&gt;
&lt;li&gt;최솟값? 최단거리? 를 구하기 위해 뭘 써야하나&lt;/li&gt;
&lt;li&gt;일단 조이스틱은 dx, dy를 활용한 방법같고&lt;/li&gt;
&lt;li&gt;범위 초과 시 처리는 있고&lt;/li&gt;
&lt;li&gt;뭔가 알파벳을 X 축, 글자위치를 Y로 본다면 이건 DFS 계열 같다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;해당 문제의 난이도 상승 원인&lt;/li&gt;
&lt;li&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;처음엔 BFS로 생각하고 BFS에 필요한 기본 재로코드를 타이핑하고 있었는데 문득 같은 단어를 치려고 해도앞으로 전진하면서 찾는 것보다 뒤로 후진하면서 찾는경우가 더 빠를 수 있다고 생각하여 BFS 가 아닌 , 이분 탐색? 에 가까운 경우로 보인거 같다&lt;/li&gt;
&lt;li&gt;그래서 알파벳 A, Z 를 기준으로 각각 0, 25로 정하고&lt;/li&gt;
&lt;li&gt;{대상문자 - A, Z - 대상문자 + 1}식을 사용해 알파벳 이동에 대한 최소거리를 계산해냈으나 테스트케이스를 실행하니 조금씩 값이 다른것을 확인&lt;/li&gt;
&lt;li&gt;그래서 놓친 것이 있나 문제 지문을 다시 살펴보니 y축 또한 이와 비슷하게 처리해야 함을 인지&lt;/li&gt;
&lt;li&gt;y구간 중 가장 긴 연속된 A 구간이 있다면 그것을 피하는게 최소 거리라고 생각되어 매 순환마다 다음 인덱스가 A 구간인지 확인하며 계산 후 정-&amp;gt;역, 역-&amp;gt;정 길이를 구한 다음 둘 중 최소값을 구함 그리고 추가로 문자열 길이 - 1 과 비교하여 최솟값을 구해서 갱신시킴&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;continue는 건너뛰기지 방문 자체는 해버림&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;가장 긴 A문자열을 체크해야하므로 정-&amp;gt;역, 역-정 전체 길이를 구하고 최솟값을 판단&lt;/li&gt;
&lt;li&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;//전체 ------------------------------
//기준 ---------|~~~~~|..............
//다음 ---------------|++++++++++|...  
// 정방향 과 역방향 은 어차피 NL -1 길이를 가지므로 묶임  
// 정방향 + 역방향  
// ((i * 2) + (전체 - 다음))
// 역방향 + 정방향  
// (((전체 - 다음) * 2) + i)&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774241846182&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.List;

public class Lv2JoyStick {
    public static void main(String[] args){
        String name = &quot;JEROEN&quot;;

        System.out.println(solution(name));
    }

    public static int solution(String name) {
        final int START = 'A'; // 65번이다
        final int END = 'Z'; // 90번이다
        final int NL = name.length(); // 문자열 마지막 인덱스

        //전체 ------------------------------
        //다음 ---------------|++++++++++|
        //기준 ---------|~~~~~|

        // 정방향 과 역방향 은 어차피 NL -1 길이를 가지므로 묶임
        // 정방향 + 역방향
        // ((i * 2) + (전체 - 다음)) % 전체
        // 역방향 + 정방향
        // (((전체 - 다음) * 2) + i) % 전체

        int x = 0;
        int y = NL - 1;
        for(int i = 0; i &amp;lt; NL; i++){
            int[] alpahDistArr = {name.charAt(i) - START, END - name.charAt(i) + 1};
            x += Math.min(alpahDistArr[0], alpahDistArr[1]);

            // 0은 초기 위치므로 계산에서 제외됨
            // next는 'A'의 마지막을 나타내는게 아니라 'A'가 아닌 다음 요소 인덱스
            int next = i + 1;
            while(next &amp;lt; NL &amp;amp;&amp;amp; name.charAt(next) == 'A') next++;

            // 배열 내 각각의 수식은 정-&amp;gt;역, 역-&amp;gt;정에 대한 전체 이동길이를 나타내며
            // 연속된 A 구간 중 가장 긴 구간이 있을 때 짧아지는 것으로 생각된다
            // 그러므로 매 순환마다 최솟값을 체크하며 갱신해야한다.

            int[] cursorDistArr = {(i * 2) + (NL - next), (NL - next) * 2 + i};
            int compareVal = Math.min(cursorDistArr[0], cursorDistArr[1]);
            y = Math.min(y, compareVal);

            System.out.println(&quot;x :&quot; + alpahDistArr[0] + &quot;, &quot; + alpahDistArr[1]);
            System.out.println(&quot;y :&quot; + y);
            System.out.println(&quot;----------------------------&quot;);
        }
        return x + y;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/72</guid>
      <comments>https://ysldev.tistory.com/72#entry72comment</comments>
      <pubDate>Mon, 23 Mar 2026 13:57:40 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 양궁대회 문제</title>
      <link>https://ysldev.tistory.com/71</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 양궁대회 문제
&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;/li&gt;
&lt;li&gt;전 챔피언과 도전자가 같은 점수 + 다른 횟수로 과녁을 적중했다면 더 많이 맞힌 쪽에 그 점수가 1번 들어감&lt;/li&gt;
&lt;li&gt;전 챔피언과 도전자가 같은 점수 + 같은 횟수로 과녁을 적중했다면 도전자에게 그 점수가 1번 들어감&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;이 문제는 전 챔피언에 대한 것을 결과로 원하므로 지거나 비기면 '-1' 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;점수는 0~10까지 존재하며 각 선수는 n번 화살을 발사&lt;/li&gt;
&lt;li&gt;info는 10~0까지의 점수를 나타내는 배열이며 각 요소는 해당 위치(점수)에 적중한 횟수를 나타냄
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;길이는 11&lt;/li&gt;
&lt;li&gt;인덱스는 점수를 의미하며 내림차순&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;n이 큰 수가 되었을 떄 경우의 수가 매우 많아짐&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;DFS 방식을 사용하여 모든 경우의 수를 구하고 최대차이 + 낮은 점수 위주의 사용 경우를 찾음&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;여러번 맞혀도 결국 점수를 얻는건 1번 분량의 점수&lt;/li&gt;
&lt;li&gt;그리고 라이언이 info를 보고 어떻게 쏴야할지 정하는 문제&lt;/li&gt;
&lt;li&gt;그렇다면 '조합식'을 구하는 문제? 조합식을 찾을 수없다면 '-1'하는 문제?&lt;/li&gt;
&lt;li&gt;근데 도전자보다 점수를 많이 얻으려면 걔가 맞힌 점수보다 많이 때려야 한다는 건데&lt;/li&gt;
&lt;li&gt;그러면 Greedy와 비슷하다고 생각됨&lt;/li&gt;
&lt;li&gt;다시 생각하지만 점수는 쟁탈전의 형태 즉, 한 점수는 한 사람에게만 귀속&lt;/li&gt;
&lt;li&gt;그러나 Greedy로 해결하기에는 경우의 수가 매우 많아져 이를 모두 체크하면서 실행되는 DFS 방식이 더 적합하다 생각&lt;/li&gt;
&lt;li&gt;DFS 코드의 구현 부분중 종료 시점의 코드를 작성하기 위해 화살을 모두 사용하거나, 마지막 인덱스에 도달 시 , DFS 재귀함수가 종료되도록 설정하였고 새로 검출된 경우의 수가 현 최대 차이보다 크면 갱신, 최대 점수 - 상대 점수, 현 점수 - 상대 점수의 차가 같다면 더 낮은 경우의 점수를 얻었을 때를 위주로 갱신하여 해결하려 했다.&lt;/li&gt;
&lt;li&gt;그러나 코드 작성 후 테스트 케이스 4개를 실행하니 3, 4 번 은 오류로 나와서 확인해보니 현재 나의 코드는 DFS 를 돌 때마다 무조건 화살을 쏘도록 되어있어 화살을 쏘지 않는다는 상황은 고려를하지 않아 이를 추가 후 다시 테스트 하니 4개의 테스트 케이스가 정답으로 표시되어 코드를 제출 후 정답인 것을 확인 함&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;DFS로 문제를 해결하는 것&lt;/li&gt;
&lt;li&gt;무조건 화살을 쏘는게 아닌, 안 쏘는 상황도 고려해야하는 것&lt;/li&gt;
&lt;li&gt;모든 경우의 수를 체크하는게 정확성 면으로는 맞지만 이 검사를 줄일 수 있다면 줄이는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774241770978&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Lv2Archery {
    public static void main(String[] args){
        int n = 10;
        int[] info = {0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3};

        for(int i : solution(n, info)){
            System.out.print(i + &quot;, &quot;);
        }
    }

    static int[] resultArr;
    static int resultDist;
    static int[] otherArr;

    public static void dfs(int n, int[] info, int cuurOperIdx){
        if(n == 0 || cuurOperIdx == 11){
            if(n &amp;gt; 0){
                info[info.length - 1] += n;
            }

            int resultSum = 0;
            int otherSum = 0;

            for(int i = 0; i &amp;lt; info.length; i++){
                if(info[i] == 0 &amp;amp;&amp;amp; otherArr[i] == 0) continue;
                else if(info[i] &amp;gt; otherArr[i]) resultSum += 10 - i;
                else otherSum += 10 - i;
            }

            int dist = resultSum - otherSum;

            if(dist &amp;gt; 0){
                if(dist &amp;gt; resultDist){
                    resultDist = dist;
                    resultArr = info.clone();
                }
                else if(resultDist == dist){
                    for(int i = info.length - 1; i &amp;gt;= 0; i--){
                        if(info[i] &amp;gt; resultArr[i]){
                            resultArr = info.clone();
                            break;
                        }
                        else if(resultArr[i] &amp;gt; info[i]) break;
                    }
                }
            }

            if(n &amp;gt; 0){
                info[info.length - 1] -= n;
            }

            return;
        }

        dfs(n, info, cuurOperIdx + 1);

        int weight = otherArr[cuurOperIdx] + 1;
        if(weight &amp;lt;= n){
            info[cuurOperIdx] += weight;
            n -= weight;
            dfs(n, info, cuurOperIdx + 1);
            // 백트래킹
            n += weight;
            info[cuurOperIdx] -= weight;
        }

    }

    public static int[] solution(int n, int[] info) {
        resultArr = new int[]{-1};
        resultDist = 0;
        otherArr = info;

        dfs(n, new int[11], 0);

        return resultArr;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래머스 코딩 테스트 문제/lv2</category>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/71</guid>
      <comments>https://ysldev.tistory.com/71#entry71comment</comments>
      <pubDate>Mon, 23 Mar 2026 13:56:26 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 택배 배달과 수거하기 문제</title>
      <link>https://ysldev.tistory.com/70</link>
      <description>&lt;pre id=&quot;code_1774241686676&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class LV2Express {
    public static void main(String[] args){
        int cap	= 2;//4;
        int n = 7;//5;
        int[] deliveries = {1, 0, 2, 0, 1, 0, 2};//{1, 0, 3, 1, 2};
        int[] pickups	= {0, 2, 0, 1, 0, 2, 0};//{0, 3, 0, 4, 0};

        System.out.print(solution(cap, n, deliveries, pickups));
    }

    public static long solution(int cap, int n, int[] deliveries, int[] pickups) {
        int reqDelCnt = 0;
        int reqPickCnt = 0;
        long dist = 0;
        for(int i = n - 1; i &amp;gt;= 0; i--){
            reqDelCnt += deliveries[i];
            reqPickCnt += pickups[i];

            int goCnt = 0;
            while(reqDelCnt &amp;gt; 0 || reqPickCnt &amp;gt; 0){
                reqDelCnt -= cap;
                reqPickCnt -= cap;
                goCnt++;
            }

            if(goCnt &amp;gt; 0){
                dist += (long)(i + 1) * 2 * goCnt;
            }
        }

        return dist;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로래머스 Lv2 택배 배달과 수거하기 문제&lt;/p&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;/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;Greedy + 역방향 스캔 + 누적 잔량 방식을 사용해 해결&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;처음에는 '최단 거리' 라는 말 때문에 BFS와 그와 비교되는 DFS 방식을 생각하였으나 '최단 거리'를 만족하려면 가장 멀리 있는 곳을 처리해야하므로 Greedy를 선택하였고 이를 만족하기 위해 역방향 스캔을 하도록 작업하였다.&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;/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;'최단 거리'라는 단어가 주어질 때 BFS, DFS 및 Greedy 등 중 어느 알고리즘을 사용할 지 판단&lt;/li&gt;
&lt;li&gt;Greedy 사용 시 경우에 따라 정방향, 역방향 중 시작을 어디로 할지 판단&lt;/li&gt;
&lt;li&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;</description>
      <category>프로그래머스 코딩 테스트 문제/lv2</category>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/70</guid>
      <comments>https://ysldev.tistory.com/70#entry70comment</comments>
      <pubDate>Mon, 23 Mar 2026 13:55:04 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 혼자 놀기의 달인 문제</title>
      <link>https://ysldev.tistory.com/69</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 혼자 놀기의 달인 문제
&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;/li&gt;
&lt;li&gt;1번 그룹의 박스를 고른 후 2번 그룹의 처음 시작 시, 발생하는 경우의 수 관리법이 필요하다는 점&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;li&gt;임의의 박스를 선택하기 때문에 처음 -&amp;gt; 마지막까지 선형 순환하는 방식을 선택하고 그에 따라 발생하는 경우의 수를 처리하는 내부 순환문을 작성&lt;/li&gt;
&lt;li&gt;1번 그룹에서 나온 박스 수와 2번 그룹에서 나온 박스 수의 곱한 값을 이전에 구했던 최대값과 비교해 나가면서 최종 Max 값을 찾음&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;li&gt;1번/2번 그룹의 박스의 곱한 값의 최대값을 구하는 방법 찾기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774241601636&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.List;

public class Lv2SoloPlay {
    public static void main(String[] args){
        int[] cards = {8,6,3,7,2,5,1,4};
        System.out.print(solution(cards));
    }

    public static int solution(int[] cards) {
        int LEN = cards.length;
        int seatNum = 1;
        int[] seat = new int[LEN + 1];
        for(int i = 0; i &amp;lt; LEN; i++) seat[seatNum++] = cards[i];

        int sum = 0;
        for(int i = 1; i &amp;lt; LEN + 1; i++){
            boolean[] marking = new boolean[LEN + 1];
            int mainSum = 0;

            for(int j = seat[i]; !marking[j]; j = seat[j]){
                mainSum += 1;
                marking[j] = true;
            }

            List&amp;lt;Integer&amp;gt; remain = new ArrayList&amp;lt;&amp;gt;();

            for(int j = 1; j &amp;lt; LEN + 1; j++){
                if(!marking[j]) remain.add(j);
            }
            boolean[] preservArr = marking.clone();

            for(int val : remain){
                int subSum = 0;
                marking = preservArr.clone();
                for(int j = seat[val]; !marking[j]; j = seat[j]){
                    subSum += 1;
                    marking[j] = true;
                }

                sum = Math.max(sum, mainSum * subSum);
            }
        }

        return sum;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래머스 코딩 테스트 문제/lv2</category>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/69</guid>
      <comments>https://ysldev.tistory.com/69#entry69comment</comments>
      <pubDate>Mon, 23 Mar 2026 13:53:40 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Lv2 [PCCP 기출문제] 3번 / 충돌위험 찾기 문제</title>
      <link>https://ysldev.tistory.com/68</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로래머스 Lv2 충돌위험 찾기 문제
&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;/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;시간(초)를 기준으로 순환문을 생성하여 각 시간에 따른 Int 자료형을 사용하는 위치 테이블을 생성해 이동 시 해당 위치에 +1 하고 해당 위치의 값이 2 이상이면 겹쳐짐으로 판단하여 이것의 개수를 카운팅함&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 로봇을 저장할 자료형을 List로 정하고 작업&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;그러나 위의 방법은 루트 요소의 길이가 2인 경우에만 정답이고 그 이상이면 문제가 발생하였음 그래서 루트의 특성인 순서를 지키기 위하여 Queue를 사용해 루트의 우선순위를 지키면서 각 요소의 도착지에 도달 시, 그 뒤에 다른 요소가 있는지 체크하고 요소가 있다면 그 요소의 정보로 다시 이동하게 끔 코드를 작성&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;li&gt;요소 길이가 길어지면 이를 해결할 방법 찾기&lt;/li&gt;
&lt;li&gt;로봇이 이동가능한 맵의 최대 영역 크기인 n*n 으로 겹쳐짐 판별 시, 메모리 과부하가 발생하므로 이를 해결할 방법 찾기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774241503908&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;

public class LV2SearchCrashRisk {
    public static void main(String[] args){
        int[][] points = {
                {1, 1},
                {1, 3}
        };
        int[][] routes = {
                {1, 2, 1, 2},
                {2, 1, 2, 1}
        };

        System.out.print(solution(points, routes));
    }

    public static class Node{
        int cx;
        int cy;
        int tx;
        int ty;
        int routeNum;

        Node(int cx, int cy, int tx, int ty, int routeNum){
            this.cx = cx;
            this.cy = cy;
            this.tx = tx;
            this.ty = ty;
            this.routeNum = routeNum;
        }

        public int getCx() {
            return cx;
        }

        public int getCy() {
            return cy;
        }

        public int getTx() {
            return tx;
        }

        public int getTy() {
            return ty;
        }

        public int getRouteNum() {
            return routeNum;
        }

        public void set(int cx, int cy, int tx, int ty, int routeNum){
            this.cx = cx;
            this.cy = cy;
            this.tx = tx;
            this.ty = ty;
            this.routeNum = routeNum;
        }

        public void addLoc(int cx, int cy){
            this.cx += cx;
            this.cy += cy;
        }

        public int compareToX(){
            int result = 0;
            if(this.cx &amp;gt; this.tx) result = -1;
            else if(this.cx &amp;lt; this.tx) result = 1;

            return result;
        }

        public int compareToY(){
            int result = 0;
            if(this.cy &amp;gt; this.ty) result = -1;
            else if(this.cy &amp;lt; this.ty) result = 1;

            return result;
        }
    }

    public static int solution(int[][] points, int[][] routes) {
        int maxX = 0;
        int maxY = 0;
        int minX = Integer.MAX_VALUE;
        int minY = Integer.MAX_VALUE;

        for(int i = 0; i &amp;lt; points.length; i++){
            int[] point = points[i];
            maxX = Math.max(maxX, point[0]);
            maxY = Math.max(maxY, point[1]);
            minX = Math.min(minX, point[0]);
            minY = Math.min(minY, point[1]);
        }

        int routeLen = routes[0].length;
        int result = 0;

        List&amp;lt;Queue&amp;lt;Node&amp;gt;&amp;gt; queueList = new ArrayList&amp;lt;&amp;gt;();
        for(int k = 0; k &amp;lt; routes.length; k++){
            Queue&amp;lt;Node&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;();
            int[] route = routes[k];
            for(int i = 0; i &amp;lt; routeLen - 1; i++){
                int[] curr = points[route[i] - 1];
                int[] next = points[route[i+1] - 1];

                queue.offer(new Node(curr[0], curr[1], next[0], next[1], k));
            }
            queueList.add(queue);
        }

        List&amp;lt;Node&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        for(Queue&amp;lt;Node&amp;gt; queue : queueList){
            list.add(queue.poll());
        }

        while(!list.isEmpty()){
            int[][] map = new int[maxX - minX + 1][maxY - minY + 1];
            Iterator&amp;lt;Node&amp;gt; it = list.iterator();

            while(it.hasNext()){
                Node node = it.next();
                map[node.cx - minX][node.cy - minY] += 1;
                int nx = node.compareToX();
                int ny = (nx != 0) ? 0 : node.compareToY();

                if(nx == 0 &amp;amp;&amp;amp; ny == 0){
                    if(!queueList.get(node.routeNum).isEmpty()){
                        Node newNode = queueList.get(node.routeNum).poll();
                        node.set(newNode.getCx(), newNode.getCy(), newNode.getTx(), newNode.getTy(), newNode.getRouteNum());
                        nx = node.compareToX();
                        ny = (nx != 0) ? 0 : node.compareToY();
                    }
                    else{
                        it.remove();
                        continue;
                    }
                }

                node.addLoc(nx, ny);
            }

            for(int[] arr : map){
                for(int a : arr){
                    System.out.print(a + &quot; &quot;);
                    if(a &amp;gt; 1) result++;
                }
            }
        }

        return result;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <author>lys4321</author>
      <guid isPermaLink="true">https://ysldev.tistory.com/68</guid>
      <comments>https://ysldev.tistory.com/68#entry68comment</comments>
      <pubDate>Mon, 23 Mar 2026 13:52:10 +0900</pubDate>
    </item>
  </channel>
</rss>