알고리즘 풀이/Java
[알고리즘][X] 메이즈 러너
Dong's Universe
2024. 3. 30. 02:03
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
static int N;
static int M;
static int K;
static int[] exit;
static int[][] info;
static int move = 0;
static List<int[]> rotatePerson = new ArrayList<>();
static int[][] people;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
info = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
info[i][j] = Integer.parseInt(st.nextToken());
}
}
// r, c, isExit 1: exit, 0: not exit
people = new int[M][3];
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < 2; j++) {
people[i][j] = Integer.parseInt(st.nextToken()) - 1;
}
}
// exit 좌표 구하기
exit = new int[2];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < 2; i++) {
exit[i] = Integer.parseInt(st.nextToken()) - 1;
}
for (int k = 0; k < K; k++) {
// System.out.println("before");
// for (int[] person : people) {
// if (person[2] == 1) {
// continue;
// }
// System.out.println(person[0] + " " + person[1]);
// }
// System.out.println();
// 1. 움직인다.
for (int i = 0; i < M; i++) {
if (people[i][2] == 1) {
continue;
}
move(people[i], info);
}
// 2. 미로가 회전한다.
rotate(people);
// System.out.println("after");
// for (int[] person : people) {
// if (person[2] == 1) {
// continue;
// }
// System.out.println(person[0] + " " + person[1]);
// }
// System.out.println();
}
System.out.println(move);
System.out.println((exit[0]+1) + " " + (exit[1]+1));
//debug
// for (int[] person : people) {
// if (person[2] == 1) {
// continue;
// }
// move(person, info);
// }
// System.out.println(Arrays.deepToString(people));
// int[][] temp = new int[][] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
//
// System.out.println(Arrays.deepToString(realRotate(temp)));
// int[] square = findSquare(people);
// System.out.println(Arrays.toString(square));
// execute(square[0], square[1], square[2]);
// System.out.println(Arrays.deepToString(people));
}
// 동시에 움직임, 사람 이미 나갔을 수 있음
private static void move(int[] person, int[][] info) {
int x = person[0];
int y = person[1];
int e = person[2];
int[] dx = {-1, 1, 0, 0};
int[] dy = {0, 0, -1, 1};
int minDist = Math.abs(x - exit[0]) + Math.abs(y - exit[1]);
int rnx = -1;
int rny = -1;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (!(0 <= nx && nx < N && 0 <= ny && ny < N && info[nx][ny] == 0)) {
continue;
}
int dist = Math.abs(nx - exit[0]) + Math.abs(ny - exit[1]);
if (dist < minDist) {
minDist = dist;
rnx = nx;
rny = ny;
break;
}
}
if (rnx == -1 && rny == -1) { // 못 움직임
return;
} else { // 움직임
move++;
if (rnx == exit[0] && rny == exit[1]) {
person[2] = 1;
return;
}
person[0] = rnx;
person[1] = rny;
}
}
private static void rotate(int[][] people) {
rotatePerson = new ArrayList<>();
int[] square = findSquare(people);
if (square == null) {
return;
}
execute(square[0], square[1], square[2]);
}
private static void execute(int r, int c, int size) {
int[][] temp = new int[size][size];
for (int i = r; i < r + size; i++) {
for (int j = c; j < c + size; j++) {
if (i == exit[0] && j == exit[1]) {
temp[i - r][j - c] = -1;
continue;
}
temp[i - r][j - c] = info[i][j];
}
}
List<Integer>[][] list = new List[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
list[i][j] = new ArrayList<>();
}
}
// System.out.println("size = " + size);
for (int[] person : rotatePerson) {
int i = person[0];
int j = person[1];
// System.out.println("rotate " + i + " " + j);
// temp[i - r][j - c] = -person[2] - 10;
list[j][size-1-i].add(person[2]);
}
// [i][j] -> [j][size-1-i]
temp = realRotate(temp);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (temp[i][j] > 0) {
temp[i][j]--;
}
}
}
for (int i = r; i < r + size; i++) {
for (int j = c; j < c + size; j++) {
if (temp[i - r][j - c] == -1) {
// System.out.println("test " + i + " " + j);
info[i][j] = 0;
exit[0] = i;
exit[1] = j;
} else if (!list[i - r][j - c].isEmpty()) {
info[i][j] = 0;
// int idx = -temp[i - r][j - c] - 10;
for (int idx : list[i-r][j-c]) {
// System.out.println(i + " " + j);
people[idx][0] = i;
people[idx][1] = j;
}
} else {
info[i][j] = temp[i - r][j - c];
}
}
}
}
private static int[][] realRotate(int[][] temp) {
int size = temp.length;
int[][] rotate = new int[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
rotate[j][size-1-i] = temp[i][j];
}
}
return rotate;
}
// 정사각형 좌상단 포인트 r, c, size
private static int[] findSquare(int[][] people) {
for (int size = 1; size < N; size++) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int ex = exit[0];
int ey = exit[1];
if (!(i <= ex && ex <= i + size && j <= ey && ey <= j + size)) {
continue;
}
boolean flag = false;
for (int k = 0; k < people.length; k++) {
int[] person = people[k];
if (person[2] == 1) {
continue;
}
int px = person[0];
int py = person[1];
if (i <= px && px <= i + size && j <= py && py <= j + size) {
// System.out.println(px + " " + py + " " + k);
rotatePerson.add(new int[] {px - i, py - j, k});
flag = true;
}
}
if (flag) {
return new int[] {i, j, size+1};
}
}
}
}
return null;
}
}
나의 풀이
- 하나의 칸에 여러 사람이 들어갈 수 있는 조건을 놓쳐서 틀렸고 디버깅이 어려웠다.
- 문제에 있는 말들은 그 어떤 것도 의미 없는 게 없다. 따라서 사소한 거라도 중요하게 보자!!