250129 마법사 상어와 파이어스톰

Jongleee·2025년 1월 29일
0

TIL

목록 보기
795/816
private static final int[] DR = { -1, 1, 0, 0 };
private static final int[] DC = { 0, 0, -1, 1 };

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());
	int q = Integer.parseInt(st.nextToken());

	int len = (int) Math.pow(2, n);
	int[][] map = new int[len][len];
	boolean[][] visited = new boolean[len][len];

	for (int r = 0; r < len; r++) {
		st = new StringTokenizer(br.readLine());
		for (int c = 0; c < len; c++) {
			map[r][c] = Integer.parseInt(st.nextToken());
		}
	}

	st = new StringTokenizer(br.readLine());
	int[] levels = new int[q];
	for (int i = 0; i < q; i++) {
		levels[i] = Integer.parseInt(st.nextToken());
	}

	for (int level : levels) {
		int size = (int) Math.pow(2, level);
		map = rotateSubgrids(map, size, len);
		map = meltIce(map, len);
	}

	int totalIce = calculateTotalIce(map);
	int largestBlock = findLargestIceBlock(map, visited, len);

	System.out.println(totalIce);
	System.out.println(largestBlock);
}

private static int[][] rotateSubgrids(int[][] map, int size, int len) {
	int[][] newMap = new int[len][len];

	for (int r = 0; r < len; r += size) {
		for (int c = 0; c < len; c += size) {
			rotate(map, newMap, r, c, size);
		}
	}
	return newMap;
}

private static void rotate(int[][] map, int[][] newMap, int r, int c, int size) {
	for (int i = 0; i < size; i++) {
		for (int j = 0; j < size; j++) {
			newMap[r + j][c + size - 1 - i] = map[r + i][c + j];
		}
	}
}

private static int[][] meltIce(int[][] map, int len) {
	int[][] newMap = new int[len][len];

	for (int i = 0; i < len; i++) {
		newMap[i] = Arrays.copyOf(map[i], len);
	}

	for (int r = 0; r < len; r++) {
		for (int c = 0; c < len; c++) {
			if (map[r][c] == 0)
				continue;
			int adjacentIce = countAdjacentIce(map, r, c, len);
			if (adjacentIce < 3) {
				newMap[r][c] = Math.max(0, map[r][c] - 1);
			}
		}
	}
	return newMap;
}

private static int countAdjacentIce(int[][] map, int r, int c, int len) {
	int count = 0;
	for (int d = 0; d < 4; d++) {
		int nr = r + DR[d];
		int nc = c + DC[d];
		if (isInBounds(nr, nc, len) && map[nr][nc] > 0) {
			count++;
		}
	}
	return count;
}

private static int calculateTotalIce(int[][] map) {
	int total = 0;
	for (int[] row : map) {
		for (int cell : row) {
			total += cell;
		}
	}
	return total;
}

private static int findLargestIceBlock(int[][] map, boolean[][] visited, int len) {
	int largestBlock = 0;

	for (int r = 0; r < len; r++) {
		for (int c = 0; c < len; c++) {
			if (map[r][c] > 0 && !visited[r][c]) {
				largestBlock = Math.max(largestBlock, bfs(map, visited, r, c, len));
			}
		}
	}
	return largestBlock;
}

private static int bfs(int[][] map, boolean[][] visited, int r, int c, int len) {
	Queue<int[]> queue = new ArrayDeque<>();
	queue.add(new int[] { r, c });
	visited[r][c] = true;
	int count = 1;

	while (!queue.isEmpty()) {
		int[] curr = queue.poll();
		int cr = curr[0], cc = curr[1];

		for (int d = 0; d < 4; d++) {
			int nr = cr + DR[d];
			int nc = cc + DC[d];
			if (isInBounds(nr, nc, len) && map[nr][nc] > 0 && !visited[nr][nc]) {
				queue.add(new int[] { nr, nc });
				visited[nr][nc] = true;
				count++;
			}
		}
	}
	return count;
}

private static boolean isInBounds(int r, int c, int len) {
	return r >= 0 && c >= 0 && r < len && c < len;
}

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

0개의 댓글

관련 채용 정보