ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 알고리즘] 10811번 바구니 뒤집기 - JAVA
    코딩테스트/백준 2023. 6. 20. 16:03

     

    이번 문제는 생각을 많이하게 된 문제라 따로 정리하려고 한다. 

     

     

     

    https://www.acmicpc.net/problem/10811

     

    10811번: 바구니 뒤집기

    도현이는 바구니를 총 N개 가지고 있고, 각각의 바구니에는 1번부터 N번까지 번호가 순서대로 적혀져 있다. 바구니는 일렬로 놓여져 있고, 가장 왼쪽 바구니를 1번째 바구니, 그 다음 바구니를 2

    www.acmicpc.net

     

     

    일단 문제의 답은 다음과 같다. 

     

    package step4;
    
    import java.io.*;
    import java.util.Arrays;
    import java.util.StringTokenizer;
    /**
     *  바구니의 총 개수 N
     *  M번 바구니의 순서를 역순으로 만든다.
     *  순서를 역순으로 바꿀 때, 역순 범위를 정하고, 그 범위 안에 들어있는 바구니의 순서를 바꾼다.
     */
    public class Q9_10811_2 {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringBuilder sb = new StringBuilder();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            int N = Integer.parseInt(st.nextToken());
            int M = Integer.parseInt(st.nextToken());
            int[] arr = new int[N];
    
            for(int i = 0; i<N; i++){
                arr[i] = i + 1;
            }
            
            for(int i=0;i<M;i++) {
                st = new StringTokenizer(br.readLine(), " ");
                int from = Integer.parseInt(st.nextToken()) -1;
                int to = Integer.parseInt(st.nextToken()) -1;
    
                for(int j =from; j<=to;j++,to--){
                    int temp = arr[j];
                    arr[j] = arr[to];
                    arr[to] = temp;
                }
    
                /**
                 * 1번부터 4번을 역순
                 *  2 1 4 3 5
                 *
                 *  from&j 0, to 3,
                 *  = 3 1 4 2 5
                 *
                 *  from&j 1, to 2
                 *  = 3 4 1 2 5
                 *
                 *  from&j 2 to 1
                 *
                 *
                 */
            }
    
            for(int i=0; i<arr.length;i++){
                sb.append(arr[i]).append(" ");
            }
    
            bw.write(sb.toString().trim());
            bw.close();
        }
    }

     

     

     

    📑 1번째 생각과 오답 

     

     

    문제는 i와 j를 입력받고 (1<=i<=j<=N) i번째부터 j번째까지의 바구니 순서를 역순으로하라였다. 근데 나는 역순이 아닌 정렬, 즉 내림차순 정렬로 생각했다. 

     

    문제는 2 1 4 3 5라는 숫자가 주어졌을 때 1번부터 4번째 있는 바구니의 순서를 역순으로 바꿔라. 

    => 3 4 1 2 5 가 나와야되는데 

     

    나는 2 1 4 3 5라는 숫자가 주어졌을 때 1번부터 4번째 있는 바구니의 순서를 내림차순 정렬해라.

    => 4 3 2 1 5 가 나와야된다 생각했다.

     

    그래서 Arrays.sort(배열, from index , to index, 정렬 방식)을 사용했다. 

     

    ★참고로 arrays.sort에서 index 사용시 from index부터 to inex -1 번째 수를 정렬한다. 즉 1번부터 4번을 index에 넣었을 시 1번부터 3번 3개만 정렬한다. 

     

     

    package step4;
    
    import java.io.*;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.StringTokenizer;
    
    /**
     *  바구니의 총 개수 N
     *  M번 바구니의 순서를 역순으로 만든다.
     *  순서를 역순으로 바꿀 때, 역순 범위를 정하고, 그 범위 안에 들어있는 바구니의 순서를 바꾼다.
     */
    public class Q9_10811 {
        public static void main(String[] args) throws IOException {
    
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringBuilder sb = new StringBuilder();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    
            StringTokenizer st = new StringTokenizer(br.readLine()," ");
            int N = Integer.parseInt(st.nextToken());
            int M = Integer.parseInt(st.nextToken());
    
            Integer[] arr = new Integer[N];
            for(int i=0; i<N;i++){
                arr[i] = i+1;
            } // 1 2 3 4 5
            for(int i=0; i<M; i++){
                st =  new StringTokenizer(br.readLine()," ");
                //Arrays.sort(arr,fromIndex,toIndex) -> fromIndex값부터 toIndex-1값까지!
                Arrays.sort(arr,Integer.parseInt(st.nextToken())-1,Integer.parseInt(st.nextToken()), Collections.reverseOrder());
            }
    
            sb.append(Arrays.toString(arr));
            bw.write(sb.toString());
            bw.close();
    
        }
    }

     

     

    이렇게 한 번 내 개념에 빠져버리면 헤어나오기 쉽지 않다. 맞는데 왜 틀리지?라는 생각에 빠져버린 원인 첫번째.

     

     

    📑 2번째 생각과 오답 

     

    for문이란? 어떤 명령문들을 반복하고자 할 대 사용하는 제어문 중 하나로 반복횟수가 정해진 경우 '주로' 사용한다. 반대로 반복횟수를 모를 경우 '주로' while문을 사용한다. 

     

    for(초기식; 반복조건(=조건식); 증감식){
         반복문이 true일 때 실행할 명령문들;

     

    초기식은 for문이 실행될 때 최초 1회만 실행되는 코드이다. 반복 조건은 true 또는 false가 나오는 식으로 true일 경우 명령문을 실행, false일 겨웅 for문을 종료하게 된다. 

     

    즉) 초기식 -> 반복조건 -> 참인 경우 for문 안으로 -> 증감식 -> 반복조건 -> 참인경우 for문 안으로 ... 이를 반복한다.

     

     

     

    정렬이 아닌 역순이구나를 깨닫고 난 후 처음 생각 했던 식은 우측과 같다. for문의 초기식이 반복될 때매다 실행되는거라 헷갈려, from의 값을 증감시켰다. 그러니 from의 값은 증감하는데 j값이 증감하지 않아 반복문이 생각했던 것 보다 더 많이 실행되는 것이다. 우측처름 작성하지 말고 좌측처럼 작성해야 생각했던 대로 코드가 실행된다.

     

     

     

     

     

    이런 사소한 허점 탓에 사간을 허비하니 처음부터 코드를 짤 때 제대로 잡고 가자. 

    반응형

    댓글

Designed by Tistory.