본문 바로가기
알고리즘/백준

[Java] BOJ 15683번 감시

by 컴공맨 2021. 5. 31.
 

15683번: 감시

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

www.acmicpc.net


풀이

카메라의 위치를 리스트를 통해 기억해두고 순열을 사용해 각 카메라마다의 방향을 정했습니다.

그 다음 기존 배열은 다음에 완성된 순열에서 사용해야하므로 배열을 복사하여 카메라를 방향과 타입에 맞게 회전시키며 모든 카메라의 감시 위치를 복사한 배열에 저장했습니다.

마지막으로 앞서 저장한 카메라의 감시 위치를 사용해 사각지대의 최소크기를 구하여 해결했습니다.


코드

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

public class Main {
	public static class Info {
		int y, x, type;

		public Info(int y, int x, int type) {
			super();
			this.y = y;
			this.x = x;
			this.type = type;
		}
	}
	
	public static int N, M, answer;
	public static List<Info> cameras;
	public static int[] cameraDir;
	public static int[][] office, copyOffice;
	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());
		
		office = new int[N][M];
		copyOffice = new int[N][M];
		cameras = new ArrayList<Info>();
		
		for (int i = 0; i < N; ++i) {
			st = new StringTokenizer(br.readLine(), " ");
			
			for (int j = 0; j < M; ++j) {
				office[i][j] = Integer.parseInt(st.nextToken());
				
				if (office[i][j] > 0 && office[i][j] < 6) {
					cameras.add(new Info(i, j, office[i][j]));
				}
			}
		}
		
		cameraDir = new int[cameras.size()];
		answer = Integer.MAX_VALUE;
		
		rotate(0);
		
		System.out.println(answer);
	}
	
	
	// 우 상 좌 하
	public static int dx[] = {1, 0, -1, 0};
	public static int dy[] = {0, -1, 0, 1};
	
	public static void copy(int[][] origin, int[][] target) {
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < M; ++j) {
				target[i][j] = origin[i][j];
			}
		}
	}
	
	public static void rotate(int cnt) {
		if (cnt == cameras.size()) {
			copy(office, copyOffice);
			
			for (int i = 0; i < cameras.size(); ++i) {
				Info info = cameras.get(i);
				
				if (info.type == 1) {
					go(info.y, info.x, cameraDir[i]);								
				}
				else if (info.type == 2) {
					for (int k = 0; k < 2; ++k) {
						int dir = (cameraDir[i] + (k * 2)) % 4;
						go(info.y, info.x, dir);
					}
				}
				else if (info.type == 3) {
					for (int k = 0; k < 2; ++k) {
						int dir = (cameraDir[i] + k) % 4;
						go(info.y, info.x, dir);
					}
				}
				else if (info.type == 4) {
					for (int k = 0; k < 3; ++k) {
						int dir = (cameraDir[i] + k) % 4;
						go(info.y, info.x, dir);
					}
				}
				else if (info.type == 5) {
					for (int k = 0; k < 4; ++k) {
						go(info.y, info.x, k);
					}
				}
			}
			
			int blindArea = 0;
			for (int i = 0; i < N; ++i) {
				for (int j = 0; j < M; ++j) {
					if (copyOffice[i][j] == 0) {
						blindArea++;
					}
				}
			}
			
			answer = (answer > blindArea) ? blindArea : answer;
			
			return;
		}
		
		for (int i = 0; i < 4; ++i) {
			cameraDir[cnt] = i;
			rotate(cnt + 1);
		}
	}
	
	public static void go(int y, int x, int dir) {
		int ny = y + dy[dir];
		int nx = x + dx[dir];
		
		while (ny >= 0 && nx >= 0 && ny < N && nx < M) {
			if (copyOffice[ny][nx] == 6) {
				return;
			}
			
			if (copyOffice[ny][nx] == 0) {
				copyOffice[ny][nx] = -1;
			}
			
			ny += dy[dir];
			nx += dx[dir];
		}
	}
}

 

pyo7410/Algorithm

1일 1커밋을 목표로! Contribute to pyo7410/Algorithm development by creating an account on GitHub.

github.com

 

'알고리즘 > 백준' 카테고리의 다른 글

[Java] BOJ 16235번 나무 재테크  (0) 2021.06.02
[Java] BOJ 5557번 1학년  (0) 2021.06.01
[Java] BOJ 17471번 게리맨더링  (0) 2021.05.30
[Java] BOJ 1600번 말이 되고픈 원숭이  (0) 2021.05.28
[Java] BOJ 14502번 연구소  (0) 2021.05.27