알고리즘
[백준 15683 JAVA] 감시
begong
2024. 3. 9. 18:35
반응형
재귀함수를 활용하는 구현 문제라고 봐야할 것 같다.
관건은 Cctv가 있는 곳에서 조건에 맞게 카메라를 돌리는것이다.
n과m이 작고, cctv의 개수도 몇개 없기 때문에 모든 카메라를 4번회전시켜도 시간초과가 나지 않을 것 같지만 혹시몰라서 회전을 몇번 안시켜도 되는 2번 5번 카메라는 최소치만 회전시키게 구현해놓았다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
class Main {
static int N;
static int M;
static int[][] map;
static ArrayList<CCTV> cctv = new ArrayList<>();
static int min = Integer.MAX_VALUE;
static int[] moveY = {-1, 0, 1, 0}; //상,우,하,좌
static int[] moveX = {0, 1, 0, -1};
static int[][] cctvView = {{1}, {1, 3}, {0, 1}, {0, 1, 3}, {0, 1, 2, 3}};
static int[] cctvRotateCount = {4, 2, 4, 4, 1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[N][M];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
int temp = Integer.parseInt(st.nextToken());
map[i][j] = temp;
if (temp != 0 && temp != 6) {
cctv.add(new CCTV(j, i, temp));
}
}
}
dfs(map, 0, cctv);
System.out.println(min);
}
static void dfs(int[][] map, int count, ArrayList<CCTV> cctv) {
if (count == cctv.size()) {
min = Math.min(min, countZero(map));
return;
}
CCTV cur = cctv.get(count);
int type = cur.type;
int x = cur.x;
int y = cur.y;
int[][] tempMap;
int cctvViewNum = cctvView[type - 1].length;
int[] cctvDir = new int[cctvViewNum];
System.arraycopy(cctvView[type - 1], 0, cctvDir, 0, cctvViewNum);
for (int i = 0; i < cctvRotateCount[type - 1]; i++) {
tempMap = mapCopy(map);
checkCctv(tempMap, cctvDir, x, y);
dfs(tempMap, count + 1, cctv);
for (int j = 0; j < cctvViewNum; j++) {
cctvDir[j] += 1;
if (cctvDir[j] >= 4) {
cctvDir[j] -= 4;
}
}
}
}
static void checkCctv(int[][] map, int[] cctvDir, int x, int y) {
for (int dir : cctvDir) {
int i = y;
int j = x;
while (N > i && i >= 0 && M > j && j >= 0 && map[i][j] != 6) {
map[i][j] = -1;
i += moveY[dir];
j += moveX[dir];
}
}
}
static int countZero(int[][] map) {
int count = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (map[i][j] == 0) count++;
}
}
return count;
}
static int[][] mapCopy(int[][] map) {
int[][] temp = new int[N][M];
for (int i = 0; i < N; i++) {
System.arraycopy(map[i], 0, temp[i], 0, M);
}
return temp;
}
}
class CCTV {
int x, y, type;
public CCTV(int x, int y, int type) {
this.x = x;
this.y = y;
this.type = type;
}
}
반응형