suheang

[백준] | JAVA, 자바 | 10811번 - 바구니 뒤집기 본문

알고리즘

[백준] | JAVA, 자바 | 10811번 - 바구니 뒤집기

suheang 2024. 2. 10. 22:18

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

 

10811번: 바구니 뒤집기

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

www.acmicpc.net


문제 요약 :

바구니를 총 N개 가지고 있고, 각각의 바구니에는 1번부터 N번까지 번호가 순서대로 적혀져 있다.

가장 왼쪽 바구니를 1번째 바구니, 그 다음 바구니를 2번째 바구니, ... , 가장 오른쪽 바구니를 N번째 바구니라고 부른다.

첫째 줄에 N (1 ≤ N ≤ 100)과 M (1 ≤ M ≤ 100)이 주어진다.

N은 바구니 개수, M은 역순으로 만들 횟수

둘째 줄부터 M개의 줄에는 바구니의 순서를 역순으로 만드는 방법이 주어진다. 방법은 i j로 나타내고, 왼쪽으로부터 i번째 바구니부터 j번째 바구니의 순서를 역순으로 만든다는 뜻이다. (1 ≤ i ≤ j ≤ N)

M번 바구니의 순서를 역순으로 만든 다음, 바구니에 적혀있는 번호를 가장 왼쪽 바구니부터 출력하는 프로그램을 작성하시오.

 

(이번 문제는 문제를 요약하기 보다 이해하기 위해 순서대로 적었다. 처음에 문제를 잘 이해하지 못해 두세 번 더 읽었던 것 같다. 문제의 예제를 대입해 보면 다음과 같다.)

10811번 문제 예제

 

1. 바구니 5개(N개) 생성, 역순으로 만들 횟수 4번(M번)

{1, 2, 3, 4, 5}

2. 1번째 바구니부터 2번째 바구니의 순서를 역순

{2, 1, 3, 4, 5}

3. 3번째 바구니부터 4번째 바구니의 순서를 역순

{2, 1, 4, 3, 5}

4. 1번째 바구니부터 4번째 바구니의 순서를 역순

{3, 4, 1, 2, 5}

5. 2번째 바구니부터 2번째 바구니의 순서를 역순

{3, 4, 1, 2, 5}


문제 풀이

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int number = sc.nextInt();
        int reverse = sc.nextInt();
        int temp = 0;

        ArrayList<Integer> basket = new ArrayList<>();
        for (int i = 1; i <= number; i++) {
            basket.add(i);
        }

        for (int i = 0; i < reverse; i++) {
            int a = sc.nextInt()-1;
            int b = sc.nextInt()-1;

            while (a < b) {
                temp = basket.get(a);
                basket.set(a, basket.get(b));
                basket.set(b, temp);
                a++;
                b--;
            }
        }

        for (int i : basket) {
            System.out.print(i + " ");
        }
    }
}

 

1. 바구니의 개수, 역순으로 변경할 횟수, 역순으로 바꾸기 위해 값을 저장할 변수 선언

2. 입력 받은 바구니 개수에 따라 번호 생성

3. 역순으로 변경할 i 번째 바구니(a), j 번째 바구니(b) 입력, 이때 인덱스가 0부터 시작하기에 입력받은 값에서 -1

4. while문을 사용해 temp에 i 번째 바구니 값을 저장하고, i 번째 바구니 값을 j 번째 바구니 값으로 변경, j 번째 바구니 값을 앞서 저장한 i 번째 바구니 값으로 변경

5. a의 값을 1 더하고 b의 값을 1 뺀 뒤 a가 b보다 커질 때까지 4번 반복

6. 역순으로 변경 완료된 값 출력


리팩토링

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        StringTokenizer st = new StringTokenizer(br.readLine());
        int number = Integer.parseInt(st.nextToken());
        int reverse = Integer.parseInt(st.nextToken());
        
        ArrayList<Integer> basket = new ArrayList<>();
        for (int i = 1; i <= number; i++) {
            basket.add(i);
        }

        for (int i = 0; i < reverse; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken()) - 1;
            int b = Integer.parseInt(st.nextToken()) - 1;
            
            while (a < b) {
                int temp = basket.get(a);
                basket.set(a, basket.get(b));
                basket.set(b, temp);
                a++;
                b--;
            }
        }

        for (int i : basket) {
            System.out.print(i + " ");
        }
        br.close();
    }
}

 

다른 사람들이 푼 내용을 확인해 보니 대부분 비슷한 풀이였다. 대신 성능을 위해 Scanner가 아닌 BufferedReader를 사용한 풀이가 있어 풀었던 코드를 Scanner에서 BufferedReader로 변경해 보았다.

 

 

아래 코드는 Scanner, 위에 코드는 BufferedReader를 사용한 코드다. 비교해보면 위에 코드가 아래 코드보다 코드 길이는 더 길어졌지만 소요된 시간과 메모리 소비가 줄어든 것을 확인 할 수 있다.