백준 10812 바구니 순서 바꾸기 [JAVA]

Ga0·2023년 3월 19일
1

baekjoon

목록 보기
1/123

이 문제 자체를 이해하는데 시간을 꽤 오래 걸려서 포스트를 하려한다!

문제 해석

문제를 이해하기 위해 예시를 들어 정리한 것은 아래와 같다.

  • 바구니의 수 (N = 8개)

  • 회전수 (M = 4회)

  • 시작 바구니 (i = 1)

  • 끝 바구니 (j = 6)

  • 기준 바구니 (k = 4)

시작 바구니와 끝바구니 사이의 순서를 바꾸는 것인데, 일단 시작 바구니는 k번째 바구니가 되고 k번째 뒤에는 k+1부터 j(끝)번째 사이의 바구니가 담아지게 되고, j+1번째부터는 i번째부터 k-1번째의 바구니가 담아지게 된다.

이러한 과정을 M번 반복해서 결과 값을 출력하는 것이 10812번 문제이다.

본격적인 문제풀이전에
나는 회전시켜 회전된 값을 저장할 바구니 배열을 하나를 더 만들었다!

  int [] basket = new int[N]; //담을 바구니 배열
  int [] rotationBasket = new int[N]; //회전을 시킨 바구니 배열

값은 이런식으로 입력 받았고,

  token = new StringTokenizer(br.readLine());
  /*배열인덱스가 0부터 시작하므로 -1*/
  int i =  Integer.parseInt(token.nextToken())-1; //시작
  int j =  Integer.parseInt(token.nextToken())-1; //끝
  int k =  Integer.parseInt(token.nextToken())-1; //기준


이런식으로 해당 i,j,k의 값을 입력받는데 하나씩 입력받을 때마다 반복해야하는 횟수는 j-i+1이라고 볼 수 있다.

     /*
     	여기서 l1은 
        i값을 기준으로 계속 증가해야하는데 i를 조건식에 사용해서 i값을 따로 저장하려고 선언한 변수이다.
        int i1 = i; 
     */
     
     // (1)에 해당되는 부분! k부터 j까지의 값을 넣는 if문
    if(k+b <= j){ //기준에서 + 반복 횟수한 값이 끝 바구니의 인덱스보다 작을 때까지만
       rotationBasket[b+i] = basket[k+b];
   }else{ //(2)에 해당되는 부분! 여기서부턴 i~k부분
       rotationBasket[b+i] = basket[i1];
       i1++; //i1값을 계속 증자시켜서 i~k부분을 j뒤에 넣어준다.
  }

 for(int b = 0; b < N; b++){
    //rotationBasket[b]값이 0이라는 것은 회전하는 값에 포함되지 않았다는 것.
   if(rotationBasket[b] != 0){ //그래서, 0을 제외한 부분을 덮어씌우기하면 된다.
     basket[b] = rotationBasket[b];
   }
 }

해답 코드(전체 코드)

  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));
          StringTokenizer token = new StringTokenizer(br.readLine());

          int N = Integer.parseInt(token.nextToken()); //바구니 개수
          int M = Integer.parseInt(token.nextToken()); //회전 횟수

          int [] basket = new int[N]; //담을 바구니 배열

          int [] rotationBasket = new int[N]; //회전을 시킨 바구니 배열

          for(int i = 0; i < basket.length; i++){
              basket[i] = i+1; //바구니에 값 1~N 순서대로 담는다.
          }

          for(int r = 0; r < M; r++){ //회전 시킬 횟수만큼 반복
              token = new StringTokenizer(br.readLine());
              /*배열인덱스가 0부터 시작하므로 -1*/
              int i =  Integer.parseInt(token.nextToken())-1; //시작
              int j =  Integer.parseInt(token.nextToken())-1; //끝
              int k =  Integer.parseInt(token.nextToken())-1; //기준

              int i1 = i; // i값을 기준으로 계속 증가해야하는데 i를 조건식에 사용해서 i값을 따로 저장해둔다.

             for(int b = 0; b < j-i+1; b++){ //여기까지가 바꾼 바구니 부분이고 바꾸지 i
                  // k부터 j까지의 값을 넣는 if문
                  if(k+b <= j){ //기준에서 + 반복 횟수한 값이 끝 바구니의 인덱스보다 작을 때까지만
                      rotationBasket[b+i] = basket[k+b];
                  }else{ //여기서부턴 i~k부분
                      rotationBasket[b+i] = basket[i1];
                      i1++; //i1값을 계속 증자시켜서 i~k부분을 j뒤에 넣어준다.
                  }
             }
             for(int b = 0; b < N; b++){
                 //rotationBasket[b]값이 0이라는 것은 회전하는 값에 포함되지 않았다는 것.
                 if(rotationBasket[b] != 0){ //그래서, 0을 제외한 부분을 덮어씌우기하면 된다.
                     basket[b] = rotationBasket[b];
                 }
             }

          }
          br.close();

          for(int i = 0; i < N; i++){ //rotationBasket.length = N
              bw.write(basket[i] + " ");
          }

          bw.flush();
          bw.close();

    }
}
  • 나머지 코드 설명은 주석을 추가해두었다.

결과

느낀점

  • 먼저, 이 문제에 대해 애를 먹었던 이유는 배열 1개로 왔다갔다 할려고 했기 때문이다.
    (물론, 배열 1개로 바꿀 수 있는 방법이 있는데,,, 내가 방법을 생각하지 못한 것도 있겠지만...)
  • 이제 와서 생각하면 배열 2개 써서 이렇게 간단히 풀릴 문제인데, 왜 이리 애를 먹었는지 모르겠다. (원래 풀땐 생각이 안난다,,,ㅎㅎㅎ)

0개의 댓글