https://www.acmicpc.net/problem/2759
알고리즘 분류를 굳이 따지자면 constructive, ad-hoc, greedy 쪽일 것 같음. 애초에 답으로 가능한 경우 어떤 것이든 출력하면 되기도 하고, 이런 류의 문제를 풀기위한 well-known 스러운 풀이도 없다고 판단되므로 논리적 추론을 통해 이 문제만의 풀이과정을 만들어야 하는 종류의 문제이다.
Brute force로 모든 경우를 보면 최대 O(30^30) 이라는 괴랄한 수가 나오므로 절대 무리..
전 일단 가장 큰 수 부터 차례대로 맨 아래로 가야한다는 부분에 포인트를 맞추고, 그럼 위에서 k개를 뒤집는 방식으로 어떻게 가장 큰 수부터 차례대로 맨 아래로 내릴지 생각해봤다.
결론적으로 제 풀이는 다음과 같음.
가장 큰 수 부터 차례대로 아래의 과정을 거침.
1. 현재 맨 아래로 내리려는 수의 위치를 찾음.
2. 원래 넣어야 할 위치(첫번째로 큰 수라면 가장 아래, 2번째로 큰 수라면 아래서 2번째, ..)라면 냅둠. (코드상 while(idx!=n))
3. 그 위치가 맨 위라면, 해당 수가 들어가야 하는 위치까지 전부 뒤집음. (코드상으로 40~41line)
4. 그렇지 않다면 찾은 인덱스까지 뒤집음 (코드상 42~43line) -> 그럼 맨 위로 올라오게 되므로 다시 '1'을 수행할 시 원하는 위치에 들어감.
이걸 반복하면 될꺼라 생각하고, 위의 ad-hoc 풀이 과정대로 구현함.
예를들어 문제의 예제 입력 1의 2번째 TC의 경우, 다음의 과정을 거침
시작 : [4 3 2 5 1]
1. 가장 큰 수인 5의 위치 찾음 -> 4번째 이므로 5를 맨 위로 올리기 위해 4번째까지 뒤집음 -> [5 2 3 4 1]
2. 다시 가장 큰 수인 5의 위치를 찾음 -> 1번째 이므로, 전체를 뒤집음 -> [1 4 3 2 5]
3. 이제 5는 완료되었으므로 냅두고 4를 찾음 -> 2번째 이므로 2번째까지 뒤집음 -> [4 1 3 2 5]
4. 이제 4를 내리기 위해 4번째까지 뒤집음 (5는 이미 답을 찾았으므로 냅둠) -> [2 3 1 4 5]
5. 다음 수인 3을 찾음. 2번째이므로 2번째까지 뒤집음 -> [3 2 1 4 5]
6. 마찬가지로 3번째까지 뒤집음 -> [1 2 3 4 5]
7. 다음 수인 2를 찾음 -> 원래 들어가야할 2번째에 있으므로 냅둠
8. 다음 수인 1을 찾음 -> 마찬가지로 이미 1번째이므로 냅둠
9. 끝
-> 최종적으로 뒤집기 과정은 총 6개로, 4 5 2 4 2 3와 같음. (문제에서 제시된 답과 다르지만 어쨌든 답이 되는 출력이라면 통과이므로 상관없음. )
https://github.com/NaHwaSa/BOJ_BaekjunOnlineJudge/blob/master/02700/BOJ_2759.java
'PS > BOJ' 카테고리의 다른 글
백준 3015 자바 - 오아시스 재결합 (BOJ 3015 JAVA) (4) | 2021.10.10 |
---|---|
백준 15779 자바 - ZigZag (BOJ 15779 JAVA) (2) | 2021.10.08 |
백준 15993 자바 - 1, 2, 3 더하기 8 (BOJ 15993 JAVA) (0) | 2021.10.07 |
백준 22866 자바 - 탑 보기 (BOJ 22866 JAVA) (0) | 2021.10.05 |
백준 12931 자바 - 두 배 더하기 (BOJ 12931 JAVA) (0) | 2021.10.05 |
댓글