developer-ellen
인간 디버거의 로그 찍기
developer-ellen
전체 방문자
오늘
어제
  • 분류 전체보기 (217)
    • 회고록 (0)
    • 취뽀 및 커리어 여정의 Stack (2)
      • SSAFY 7기 (2)
    • 프로그래밍공부 (24)
      • c++ (0)
      • JAVA (3)
      • Spring (5)
      • design pattern (3)
      • BackDB (1)
      • Servlet&JSP (3)
      • Vue (4)
      • JPA (4)
      • Infra (1)
      • Linux (0)
    • AI (3)
      • papers (3)
      • trend (0)
    • 프로젝트진행 (0)
      • 데이터베이스 (0)
      • 서버개발 (0)
      • 인공지능 (0)
      • 하루정리 (0)
    • 포트폴리오 (0)
    • 알고리즘 (158)
      • 알고리즘문풀 (155)
      • 알고리즘공부 (3)
    • 통계공부 (15)
      • 시계열분석 (15)
      • 회귀분석 (0)
    • CS (14)
      • 컴퓨터네트워크 (4)
      • 운영체제 (8)
      • 데이터베이스 (2)
    • 주저리주저리 (0)
      • 필사 (0)
    • 취업관련정보 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 삼성코테기출자바풀이
  • 삼성코테기출
  • AR모형
  • 카카오코테java풀이
  • 삼성코테자바풀이
  • Arima
  • 시계열
  • SW역량테스트파이썬
  • 삼성코테구현풀이
  • 카카오코테
  • 코테파이썬
  • SW역량테스트파이썬풀이
  • 운영체제인터럽트
  • 데이터분석
  • 삼성코테자바준비
  • 삼성코테구현문제추천
  • ARIMA모형
  • 백준파이썬풀이
  • 통계분석
  • 삼성코테파이썬풀이
  • 통계학
  • BOJ파이썬풀이
  • 시계열분석
  • 삼성코테파이썬준비
  • c++ 빌더 패턴
  • c++디자인패턴
  • 삼성코테자바꿀팁
  • MA모형
  • 삼성코테파이썬
  • 삼성코테준비

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
developer-ellen

인간 디버거의 로그 찍기

알고리즘/알고리즘문풀

BOJ - 감시 15683번 (Java)

2022. 4. 21. 01:15

❓ 문제 - 백준 감시 15683번 - JAVA 풀이법

출처 

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

 

 

📝 문제해결법

1. 이 문제는 DFS+구현으로 풀었다.

  • 각 CCTV의 타입을 받아서 각 타입에 맞춰서 회전된 상태를 조합하여 사각지대의 최소값을 찾는다.
  • dx, dy로 방향 북(0), 남(1), 서(2), 동(3)으로 이동할 수 있도록 구현한다.
  • CCTV 타입이 1인 경우 90도 회전할 수 있는 경우는 북(0) / 남(1) / 서(2) / 동(3)  4가지 경우이다.
  • CCTV 타입이 2인 경우 90도 회전할 수 있는 경우는 서(2), 동(3) / 북(0), 남(1) 2가지 경우이다.
  • CCTV 타입이 3인 경우 90도로 회전할 수 있는 경우는 북(0), 동(3) / 남(1), 3(동) / 남(1), 서(2) / 북(0), 서(2) 4가지 경우이다.
  • CCTV 타입이 4인 경우는 90도로 회전할 수 있는 경우는 북(0), 서(2), 동(3) / 북(0), 남(1), 동(3) / 남(1), 서(2), 동(3) / 북(0), 남(1), 서(2) 4가지 경우이다.
  • CCTV 타입이 5인 경우는 북(0), 남(1), 서(2), 동(3) 1가지 경우이다.
  • 각 CCTV의 있는 위치 x, y, type을 cctv list에 넣어준다. 그 후 dfs(조합)으로 각 cctv마다 특정 경우에 조합으로 감시를 했을 때 사각지대가 얼마인지 구한 후 최솟값을 갱신한다. 
  • 사각지대를 구할 때는 check() 함수를 활용한다.

 

💻 소스코드

// BOJ - 감시 (15683번)
// DFS(조합)

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

public class Main_15683 {
	
	public static int[] dx = {-1, 1, 0, 0};
	public static int[] dy = {0, 0, -1, 1};
	
	public static int[][][] mode = {{{0}}, {{0}, {1}, {2}, {3}}, {{2, 3}, {0, 1}},
			{{0, 3}, {1, 3}, {1, 2}, {0, 2}},
			{{0, 2, 3}, {0, 1, 3}, {1, 2, 3}, {0, 1, 2}},
			{{0, 1, 2, 3}}};
	public static ArrayList<Node> cctv;
	public static class Node {
		int x;
		int y;
		int type;
		public Node(int x, int y, int type) {
			this.x= x;
			this.y= y;
			this.type = type;
		}
	}
	public static int n, m, ans;
	public static int[][] map;	
	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());
		cctv = new ArrayList<>();
		int zero_cnt = 0;
		int[][] map = new int[n][m];
		for(int i=0;i<n;i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for(int j=0;j<m;j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
				if(map[i][j] >= 1 && map[i][j] <= 5){
					cctv.add(new Node(i, j, map[i][j]));
				} else if(map[i][j] == 0) zero_cnt++;
			}
		}
		ans = zero_cnt;
		combination(0, cctv.size(), map);
		System.out.println(ans);
	}
	
	
	public static void combination(int depth, int r, int[][] map) {
		if(depth == r) {
			int cnt = check(map);
			ans = Math.min(ans, cnt);
			return;
		}
		int cctv_type = cctv.get(depth).type;
		int x = cctv.get(depth).x;
		int y = cctv.get(depth).y;
		
		
		for(int i=0;i<mode[cctv_type].length;i++) {
			int[][] map_copy = new int[n][m];
			for(int k=0;k<n;k++) {
				map_copy[k] = map[k].clone();
			}
			
			for(int j=0;j<mode[cctv_type][i].length;j++){
				int dir = mode[cctv_type][i][j];
		
				int nx = x + dx[dir];
				int ny = y + dy[dir];
				while (true) {
					if(nx < 0 || nx >= n || ny < 0 || ny >= m) {
						break;
					}
					
					if(map[nx][ny] == 6) {
						break;
					}
					map_copy[nx][ny] = -1;
					nx += dx[dir];
					ny += dy[dir];
				}
			}

			
			combination(depth+1, r, map_copy);
		}
	}
	
	public static int check(int[][] map) {
		int cnt = 0;
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				if(map[i][j] == 0) {
					cnt++;
				}
			}
		}
		return cnt;
	}
	
	
	

}

 

'알고리즘 > 알고리즘문풀' 카테고리의 다른 글

BOJ - 드래곤 커브 15685번 (JAVA)  (0) 2022.04.21
BOJ - 사다리 조작 15684번 (JAVA)  (0) 2022.04.21
BOJ - 로봇 청소기 14503번 (JAVA)  (0) 2022.04.17
BOJ - 테트로미노 14500번 (JAVA)  (0) 2022.04.12
BOJ - 주사위 굴리기 14499번 (JAVA)  (0) 2022.04.11
    '알고리즘/알고리즘문풀' 카테고리의 다른 글
    • BOJ - 드래곤 커브 15685번 (JAVA)
    • BOJ - 사다리 조작 15684번 (JAVA)
    • BOJ - 로봇 청소기 14503번 (JAVA)
    • BOJ - 테트로미노 14500번 (JAVA)
    developer-ellen
    developer-ellen

    티스토리툴바