241119 What's Up With Gravity

Jongleee·3일 전
0

TIL

목록 보기
734/737
private static class Point {
	int y, x, dir, cost;

	Point(int y, int x, int dir, int cost) {
		this.y = y;
		this.x = x;
		this.dir = dir;
		this.cost = cost;
	}
}

public static void main(String[] args) throws Exception {
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	StringTokenizer st = new StringTokenizer(br.readLine());
	int rows = Integer.parseInt(st.nextToken());
	int cols = Integer.parseInt(st.nextToken());

	char[][] map = new char[rows][cols];
	boolean[][][] visited = new boolean[4][rows][cols];
	int startY = 0, startX = 0;

	for (int i = 0; i < rows; i++) {
		String input = br.readLine();
		for (int j = 0; j < cols; j++) {
			map[i][j] = input.charAt(j);
			if (map[i][j] == 'C') {
				map[i][j] = '.';
				startY = i;
				startX = j;
			}
		}
	}

	ArrayDeque<Point> queue = new ArrayDeque<>();
	queue.offer(new Point(startY, startX, 2, 0));
	visited[2][startY][startX] = true;

	int result = -1;
	int[] dirY = { -1, 0, 1, 0 };
	int[] dirX = { 0, 1, 0, -1 };

	while (!queue.isEmpty()) {
		Point current = queue.poll();

		if (map[current.y][current.x] == 'D') {
			result = current.cost;
			break;
		}

		int nextY = current.y + dirY[current.dir];
		int nextX = current.x + dirX[current.dir];

		if (!isValid(rows, cols, nextY, nextX))
			continue;
		if (visited[current.dir][nextY][nextX])
			continue;

		if (map[nextY][nextX] == '#') {
			moveHorizontally(rows, cols, current, map, visited, queue);
			reverseGravity(current, visited, queue);
			continue;
		}

		visited[current.dir][nextY][nextX] = true;
		queue.offerFirst(new Point(nextY, nextX, current.dir, current.cost));
	}

	System.out.println(result);
}

private static void moveHorizontally(int rows, int cols, Point current, char[][] map, boolean[][][] visited,
		ArrayDeque<Point> queue) {
	if (isValid(rows, cols, current.y, current.x - 1) && map[current.y][current.x - 1] != '#'
			&& !visited[current.dir][current.y][current.x - 1]) {
		visited[current.dir][current.y][current.x - 1] = true;
		queue.offerFirst(new Point(current.y, current.x - 1, current.dir, current.cost));
	}

	if (isValid(rows, cols, current.y, current.x + 1) && map[current.y][current.x + 1] != '#'
			&& !visited[current.dir][current.y][current.x + 1]) {
		visited[current.dir][current.y][current.x + 1] = true;
		queue.offerFirst(new Point(current.y, current.x + 1, current.dir, current.cost));
	}
}

private static void reverseGravity(Point current, boolean[][][] visited, ArrayDeque<Point> queue) {
	int reverseDir = (current.dir + 2) % 4;
	if (!visited[reverseDir][current.y][current.x]) {
		visited[reverseDir][current.y][current.x] = true;
		queue.offerLast(new Point(current.y, current.x, reverseDir, current.cost + 1));
	}
}

private static boolean isValid(int rows, int cols, int y, int x) {
	return y >= 0 && x >= 0 && y < rows && x < cols;
}

출처:https://www.acmicpc.net/problem/5827

0개의 댓글