-
[백준 알고리즘] 10811번 바구니 뒤집기 - JAVA코딩테스트/백준 2023. 6. 20. 16:03
이번 문제는 생각을 많이하게 된 문제라 따로 정리하려고 한다.
https://www.acmicpc.net/problem/10811
일단 문제의 답은 다음과 같다.
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값이 증감하지 않아 반복문이 생각했던 것 보다 더 많이 실행되는 것이다. 우측처름 작성하지 말고 좌측처럼 작성해야 생각했던 대로 코드가 실행된다.
이런 사소한 허점 탓에 사간을 허비하니 처음부터 코드를 짤 때 제대로 잡고 가자.
반응형'코딩테스트 > 백준' 카테고리의 다른 글
[백준] 2908번 - 숫자 뒤집기(JAVA) (0) 2023.07.07 [백준 알고리즘] 단계별로 풀어보기 - 4단계 1차원 배열 JAVA (0) 2023.06.20 [백준 알고리즘] 단계별로 풀어보기 - 3단계 반복문 JAVA (0) 2023.06.02 [백준 알고리즘] 단계별로 풀어보기 - 2단계 조건문 JAVA (0) 2023.04.27 [백준 알고리즘] 단계별로 풀어보기 1단계 JAVA (0) 2023.04.14