알고리즘(백준 등) 공부/백준(자바)
백준 1327번: 소트 게임
posite
2026. 3. 18. 12:02
https://www.acmicpc.net/problem/1327
1~n까지 수가 랜덤으로 나열되어 있을 때, 특정 위치의 수 부터 오른쪽으로 k개까지 뒤집어 정렬시키는 최소 횟수를 구하는 문제이다.
n, k가 충분히 작으므로 BFS와 Set을 이용하여 특정 위치마다 뒤집고 정렬된 상태라면 횟수를 반환하게 풀었다.
수열을 int[]로 정의하였으며, 정렬된 상태를 따로 확인하지 않고 정렬된 수열과 비교하여 현재 상태가 같으면 뒤집은 횟수를 반환한다.
int[] board = new int[n];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
board[i] = Integer.parseInt(st.nextToken());
}
br.close();
int[] sorted = board.clone();
Arrays.sort(sorted);
현재 상태를 나타내는 Numbers 클래스를 구성하였으며, BFS로 탐색한다. 탐색은 특정 위치에서 뒤집었을 때 새로운 상태라면 큐에 추가한다. 이전에 존재한 상태인지 확인하기 위해 Arrays.toString()으로 문자열로 바꾸고 Set<String>에 add() 시 이미 있는 값이면 false를 반환하므로 이를 이용하여 존재 여부를 파악하였다. 큐가 비었다면 정렬 불가한 상태이므로 -1을 출력한다.
Set<String> set = new HashSet<>();
set.add(Arrays.toString(board));
Deque<Numbers> queue = new ArrayDeque<>();
queue.add(new Numbers(board.clone()));
while (!queue.isEmpty()) {
Numbers current = queue.remove();
if (Arrays.equals(sorted, current.numbers)) {
System.out.print(current.count);
return;
}
for (int i = 0; i + k - 1 < n; i++) {
int[] now = current.numbers.clone();
for (int j = 0; j < k / 2; j++) {
int temp = now[i + j];
now[i + j] = now[i + k - j - 1];
now[i + k - j - 1] = temp;
}
if (set.add(Arrays.toString(now))) {
queue.add(new Numbers(now, current.count + 1));
}
}
}
System.out.print("-1");
결과 코드는 다음과 같다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
public class 소트게임1327 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken()), k = Integer.parseInt(st.nextToken());
int[] board = new int[n];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
board[i] = Integer.parseInt(st.nextToken());
}
br.close();
int[] sorted = board.clone();
Arrays.sort(sorted);
Set<String> set = new HashSet<>();
set.add(Arrays.toString(board));
Deque<Numbers> queue = new ArrayDeque<>();
queue.add(new Numbers(board.clone()));
while (!queue.isEmpty()) {
Numbers current = queue.remove();
if (Arrays.equals(sorted, current.numbers)) {
System.out.print(current.count);
return;
}
for (int i = 0; i + k - 1 < n; i++) {
int[] now = current.numbers.clone();
for (int j = 0; j < k / 2; j++) {
int temp = now[i + j];
now[i + j] = now[i + k - j - 1];
now[i + k - j - 1] = temp;
}
if (set.add(Arrays.toString(now))) {
queue.add(new Numbers(now, current.count + 1));
}
}
}
System.out.print("-1");
}
static class Numbers {
int[] numbers;
int count = 0;
public Numbers(int[] numbers) {
this.numbers = numbers;
}
public Numbers(int[] numbers, int count) {
this.numbers = numbers.clone();
this.count = count;
}
@Override
public String toString() {
return count + " " + Arrays.toString(numbers);
}
}
}