새소식

알고리즘 문제풀이/BOJ

[백준 온라인 저지(BOJ), 브루트 포스] 삼성 코딩 테스트 문제 :: 15683번 감시 자바 풀이

  • -

이 문제는 난이도가 조금 있다고 생각해요

처음에 어떻게 풀어야 될까 고민을 좀 많이 했어요

코드만 본다면 어려워 보이진 않지만 그동안 풀었던 브루트 포스 문제랑은 조금 달랐어요

cctv마다 방향을 4가지 바꿔서 돌려줘야 했기 떄문이었어요

 

문제는 아래 사이트에서 풀어보실 수 있어요

https://www.acmicpc.net/problem/15683

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감시할 수 있는 방법은 다음과 같다. 1번 CCTV는 한 쪽 방향만 감시할 수 있다. 2번과 3번은 두 방향을 감시할 수 있는데, 2번은 감시하는 방향이 서로 반대방향이어야 하고, 3번은 직각 방향이어야 한다. 4번은 세 방향, 5번은 네 방향을 감시할

www.acmicpc.net

 

저는 CCTV 클래스를 만들어서 입력받을 때 cctv의 위치와 cctv번호를 저장했어요

그리고 dfs방식으로 문제를 풀었어요. 방향을 한 번씩 바꿔가면서요

예를들어 cctv가 3개가 있다면 1,2번 cctv는 그대로 두고 3번 cctv를 4가지 방향으로 모두 돌려봐요

그 다음은 2번 cctv를 90도 방향으로 한 번 돌리고 3번 cctv를 다시 4가지 방향으로 모두 돌려요

이러한 식으로 모든 경우를 계산했어요

 

이떄 1-4번 cctv마다 감시할 수 있는 영역이 다르기 때문에

함수를 모두 따로 만들어서 계산해주었어요

그렇게 map을 바꿔주고 사각 지대의 크기를 저장해주었어요

그렇게 모든 경우의 사각 지대의 크기를 저장해두고 collections를 이용해서 최소값을 출력해주었어요

 

아래에 코드 올려놓은 깃 허브 주소있으니 참고하세요!!

https://github.com/wlgh325/BOJ_answer/tree/master/15683(Surveillance)

 

wlgh325/BOJ_answer

Contribute to wlgh325/BOJ_answer development by creating an account on GitHub.

github.com

 

<백준 온라인 저지 15683번 감시 자바 풀이>

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

class CCTV{
	int x;
	int y;
	int num;
	int dir;
	
	CCTV(int x, int y, int num){
		this.x = x;
		this.y = y;
		this.num = num;
	}

	CCTV(CCTV cctv){
		this.x = cctv.x;
		this.y = cctv.y;
		this.num = cctv.num;
		this.dir = cctv.dir;
	}
}

class Main {
	// 사각지대 : CCTV가 감시할 수 없는 영역
	// cctv 회전 가능 (90도)
	
	// 사각지대 최소 값 구하기 ( 0의 개수가 최소 )
	
	
	/*	
		0: 빈칸
		6: 벽
		1~5: cctv
	*/
	static int[][] map;	// 사무실
	static ArrayList<Integer> sumList;
	static ArrayList<CCTV> arrList;
	static int height;
	static int width;
	static boolean[] visited;
	static ArrayList<CCTV> comb;
	static int cctvNum;

	// 모든 경우 따져서 0의 개수가 최소가 되는 경우 구하기
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String input = br.readLine();
		String[] temp = input.split(" ");
		height = Integer.parseInt(temp[0]);
		width = Integer.parseInt(temp[1]);

		map = new int[height][width];
		arrList = new ArrayList<>();
		
		sumList = new ArrayList<>();
		comb = new ArrayList<>();

		for(int i=0; i<height; i++){
			String input2 = br.readLine();
			String[] temp2 = input2.split(" ");
			for(int j=0; j<width; j++){
				int temp_num = Integer.parseInt(temp2[j]);
				if(temp_num !=0 && temp_num != 6){
					CCTV cctv = new CCTV(i,j,temp_num);
					arrList.add(cctv);
				}
				map[i][j] = temp_num;
			}
		}

		cctvNum = arrList.size();
		visited = new boolean[cctvNum];

		// dir을 하나씩 바꿔가면서 해야함
		dfs(0);

		System.out.println(Collections.min(sumList));
	}

	static void dfs(int r){
		if(r==cctvNum){
			start();
			return;
		}
		for(int i=0; i<4; i++){
			arrList.get(r).dir = i;
			dfs(r+1);
		}
		
	}

	static void start(){
		ArrayList<CCTV> copyList = new ArrayList<>();;
		int[][] tempMap;

		for(int j=0; j< arrList.size(); j++){
			copyList.add(new CCTV(arrList.get(j)));
		}
		
		tempMap = deepCopy(map);
		for(int j=0; j<cctvNum; j++){
			surveillance(tempMap, copyList.get(j));
		}
		sumList.add(calCulate(tempMap));
	}
	
	static int[][] deepCopy(int[][] original2){
		if(original2 == null) return null;
		int[][] result = new int[original2.length][original2[0].length];
		 
		for(int i=0; i<original2.length; i++){
			System.arraycopy(original2[i], 0, result[i], 0, original2[0].length);
		}
		 
		return result;
	}

	static int calCulate(int[][] map){
		int sum=0;
		for(int i=0; i<height; i++){
			for(int j=0; j<width; j++){
				if(map[i][j] ==0)
					sum+=1;
			}
		}

		return sum;
	}

	static void surveillance(int[][] map, CCTV cctv){
		switch(cctv.num){
			case 1:
				surveillance1(map, cctv);
				break;
			case 2:
				surveillance2(map,cctv);
				break;
			case 3:
				surveillance3(map, cctv);
				break;
			case 4:
				surveillance4(map, cctv);
				break;
			case 5:
				surveillance5(map, cctv);
		}
	}

	// 0: 북
	// 1: 동
	// 2: 남
	// 3: 서
	static void surveillance1(int[][] map, CCTV cctv){
		switch(cctv.dir){
			case 0:
				surveillanceNorth(map, cctv);
				break;
			case 1:
				surveillanceEast(map, cctv);
				break;
			case 2:
				surveillanceSouth(map, cctv);
				break;
			case 3:
				surveillanceWest(map, cctv);

		}
	}

	// 0: 가로
	// 1: 세로
	static void surveillance2(int[][] map, CCTV cctv){
		switch(cctv.dir){
			case 0:
				surveillanceEast(map, cctv);
				surveillanceWest(map, cctv);
				break;
			case 1:
				surveillanceNorth(map, cctv);
				surveillanceSouth(map, cctv);
		}
	}

	// 0: 북, 동
	// 1: 동, 남
	// 2: 남, 서
	// 3: 서, 북
	static void surveillance3(int[][] map, CCTV cctv){
		switch(cctv.dir){
			case 0:
				surveillanceNorth(map, cctv);
				surveillanceEast(map, cctv);
				break;
			case 1:
				surveillanceEast(map, cctv);
				surveillanceSouth(map, cctv);
				break;
			case 2:
				surveillanceSouth(map,cctv);
				surveillanceWest(map, cctv);
				break;
			case 3:
				surveillanceWest(map,cctv);
				surveillanceNorth(map, cctv);
		}
	}

	// 0: 동, 서, 북
	// 1: 동, 남, 북
	// 2: 동, 서, 남
	// 3: 서, 남, 북
	static void surveillance4(int[][] map, CCTV cctv){
		switch(cctv.dir){
			case 0:
				surveillanceEast(map, cctv);
				surveillanceWest(map, cctv);
				surveillanceNorth(map, cctv);
				break;
			case 1:
				surveillanceEast(map, cctv);
				surveillanceSouth(map, cctv);
				surveillanceNorth(map, cctv);
				break;
			case 2:
				surveillanceEast(map, cctv);
				surveillanceWest(map, cctv);
				surveillanceSouth(map, cctv);
				break;
			case 3:
				surveillanceWest(map, cctv);
				surveillanceSouth(map, cctv);
				surveillanceNorth(map, cctv);

		}
	}

	static void surveillance5(int[][] map, CCTV cctv){
		surveillanceEast(map, cctv);
		surveillanceWest(map, cctv);
		surveillanceSouth(map, cctv);
		surveillanceNorth(map, cctv);
	}

	static boolean isWall(int i){
		if(i == 6)
			return true;
		return false;
	}

	static void surveillanceNorth(int[][] map, CCTV cctv){
		for(int i=1; cctv.x - i>=0; i++){
			if(isWall(map[cctv.x-i][cctv.y]))
				break;
			map[cctv.x-i][cctv.y] = 7;
		}
	}

	static void surveillanceEast(int[][] map, CCTV cctv){
		for(int i=1; cctv.y + i <width; i++){
			if(isWall(map[cctv.x][cctv.y +i])){
				break;
			}
			map[cctv.x][cctv.y + i] = 7;
		}
	}

	static void surveillanceSouth(int[][] map, CCTV cctv){
		for(int i=1; cctv.x +i <height; i++){
			if(isWall(map[cctv.x +i][cctv.y]))
				break;
			map[cctv.x+i][cctv.y] = 7;
		}
	}

	static void surveillanceWest(int[][] map,CCTV cctv){
		for(int i=1; cctv.y - i>=0; i++){
			if(isWall(map[cctv.x][cctv.y -i]))
				break;
			map[cctv.x][cctv.y - i] = 7;
		}
	}
}

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.