티스토리 뷰

문제보러가기

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감��

www.acmicpc.net

이문제는 시뮬레이션과 dfs를 합쳐서 구현을 하였다. 문제 자체는 심플한데 구현하기는 꽤 까다로운 문제였던 것 같다.

 

 

 

 

문제풀이

-주어진 배열에서 CCTV일 경우 해당 인덱스와 CCTV번호를 Camera객체로 만들어서 list에 저장한다.

-list에 담긴 Camera객체를 하나씩 확인하며 가능한 방향에 대한 모든 map상태를 체크한다.

-가능한 방향이라면 monitor함수를 통해 map상태를 갱신하며 list에 담긴 다음 Camera객체를 확인하며 진행한다.

-가능한 방향이 끝나고 다른 방향을 탐색할 때는 map상태를 돌려놓은 다음 전해줘 야하기 때문에 copyMap을 사용한다.

-list에 담긴 전체 Camera객체를 다 탐색하면 감시할 수 있는 배열 인덱스를 max값과 비교하여 max값을 경신해준다.

-가장 적은 사각지대를 찾는 것이므로 전체 배열 n*m - (감시할 수 있는 공간 m) - (벽 공간)-(CCTV 숫자인 list.size())가 답이 된다.

 

 

 

 

 

 

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {

	static int n, m;
	static int[][] map;
	static int max = Integer.MIN_VALUE;
	static ArrayList<Camera> list;
	static int listSize;

	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		st = new StringTokenizer(br.readLine());
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		map = new int[n][m];

		list = new ArrayList<>();
		int wall = 0;
		for (int i = 0; i < n; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 0; j < m; j++) {
				int val = Integer.parseInt(st.nextToken());
				map[i][j] = val;

				if (val != 0 && val != 6) {
					list.add(new Camera(i, j, val));
				}
				if (val == 6) {
					wall++;
				}

			}
		}
		listSize = list.size();
		dfs(0, 0);
		System.out.println(n * m - max - wall - listSize);

	}

	static void dfs(int idx, int cnt) {
		
		if (idx == listSize) {
			max = Math.max(max, cnt);
			return;
		}
		int[][] copyMap = new int[n][m];
		// 동서남북 0123
		switch (list.get(idx).num) {
		case 1:
			for (int i = 0; i < 4; i++) {
				int preCnt = cnt;
				for (int j = 0; j < copyMap.length; j++) {
					System.arraycopy(map[j], 0, copyMap[j], 0, m);
				}
				cnt = monitor(list.get(idx), cnt, i);

				dfs(idx + 1, cnt);
				cnt = preCnt;
				for (int j = 0; j < copyMap.length; j++) {
					System.arraycopy(copyMap[j], 0, map[j], 0, m);
				}
			}
			break;
		case 2:
			for (int i = 0; i < 2; i++) {
				int preCnt = cnt;
				for (int j = 0; j < copyMap.length; j++) {
					System.arraycopy(map[j], 0, copyMap[j], 0, m);
				}
				cnt = monitor(list.get(idx), cnt, i);
				cnt = monitor(list.get(idx), cnt,i + 2);
				dfs(idx + 1, cnt);
				cnt = preCnt;
				for (int j = 0; j < copyMap.length; j++) {
					System.arraycopy(copyMap[j], 0, map[j], 0, m);
				}
			}
			break;
		case 3:
			for (int i = 0; i < 4; i++) {
				int preCnt = cnt;
				for (int j = 0; j < copyMap.length; j++) {
					System.arraycopy(map[j], 0, copyMap[j], 0, m);
				}
				cnt = monitor(list.get(idx), cnt,  i);
				cnt = monitor(list.get(idx), cnt, (i + 1) % 4);
				dfs(idx + 1, cnt);
				cnt = preCnt;
				for (int j = 0; j < copyMap.length; j++) {
					System.arraycopy(copyMap[j], 0, map[j], 0, m);
				}
			}
			break;
		case 4:
			for (int i = 0; i < 4; i++) {
				int count = 0;
				int preCnt = cnt;
				for (int k = 0; k < copyMap.length; k++) {
					System.arraycopy(map[k], 0, copyMap[k], 0, m);
				}
				for (int j = i; count < 3; j++) {
					cnt = monitor(list.get(idx), cnt,  j % 4);
					count++;
				}
				dfs(idx + 1, cnt);
				cnt = preCnt;
				for (int j = 0; j < copyMap.length; j++) {
					System.arraycopy(copyMap[j], 0, map[j], 0, m);
				}
			}
			break;
		case 5:
			int preCnt = cnt;
			for (int j = 0; j < copyMap.length; j++) {
				System.arraycopy(map[j], 0, copyMap[j], 0, m);
			}
			for (int i = 0; i < 4; i++) {
				cnt = monitor(list.get(idx), cnt, i);
			}
			dfs(idx + 1, cnt);
			cnt = preCnt;
			for (int j = 0; j < copyMap.length; j++) {
				System.arraycopy(copyMap[j], 0, map[j], 0, m);
			}
			break;
		}
	}

	static int monitor(Camera c, int cnt, int dir) {
		switch (dir) {
		case 0:
			for (int i = c.y; i < m; i++) {
				if (map[c.x][i] == 0) {
					map[c.x][i] = -1;
					cnt++;
				} else if (map[c.x][i] == 6) {
					break;
				}
			}
			break;
		case 1:
			for (int i = c.x; i < n; i++) {
				if (map[i][c.y] == 0) {
					map[i][c.y] = -1;
					cnt++;
				} else if (map[i][c.y] == 6) {
					break;
				}
			}
			break;
		case 2:
			for (int i = c.y; i >= 0; i--) {
				if (map[c.x][i] == 0) {
					map[c.x][i] = -1;
					cnt++;
				} else if (map[c.x][i] == 6) {
					break;
				}
			}
			break;
		case 3:
			for (int i = c.x; i >= 0; i--) {
				if (map[i][c.y] == 0) {
					map[i][c.y] = -1;
					cnt++;
				} else if (map[i][c.y] == 6) {
					break;
				}
			}
			break;
		}

		return cnt;
	}


}

class Camera {
	int x;
	int y;
	int num;

	Camera(int x, int y, int num) {
		this.x = x;
		this.y = y;
		this.num = num;
	}
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함