본문 바로가기

Problem Solving/SWEA

[SWEA] 1953. 탈주범 검거.java

728x90
반응형
SMALL

SWEA에서 사람 탈주범 검거를 자바를 통해 풀어 보았다. 

 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

1953. 탈주범 검거.java

 

GitHub - tomy9729/Algorithm: 🐗 내가 직접 작성한 내 코드 🐗

🐗 내가 직접 작성한 내 코드 🐗. Contribute to tomy9729/Algorithm development by creating an account on GitHub.

github.com

 

1953번 탈주범 검거

문제

교도소로 이송 중이던 흉악범이 탈출하는 사건이 발생하여 수색에 나섰다.

탈주범은 탈출한 지 한 시간 뒤, 맨홀 뚜껑을 통해 지하터널의 어느 한 지점으로 들어갔으며,

지하 터널 어딘가에서 은신 중인 것으로 추정된다.

터널끼리 연결이 되어 있는 경우 이동이 가능하므로 탈주범이 있을 수 있는 위치의 개수를 계산하여야 한다.

탈주범은 시간당 1의 거리를 움직일 수 있다.

지하 터널은 총 7 종류의 터널 구조물로 구성되어 있으며 각 구조물 별 설명은 [표 1]과 같다.

설명

기본적으로 BFS를 통해 탈주번이 이동할 수 있는 파이프를 세는 문제이다. 단 각 파이프는 이동할 수 있는 방향이 정해져 있으며 해당 방향으로 이동하려면 다음 파이프와 이어져 있어야 한다. 다음 그림을 보자.

 

(0,1)에서 파이프는 위 방향을 향하고 있으나 (0,0)에 있는 파이프와 연결되어 있지 않기 때문에 (0,1)에서 (0,0)으로는 이동할 수 없다. 이를 확인하기 위해 다음 이동할 위치에 있는 파이프가 현재 파이프가 가는 방향의 반대 방향으로 갈 수 있는지 확인했다. 만약 이 조건을 만족한다면 해당 파이프로 방문이 가능하다.

 

출발점을 기준으로 0으로 시작하여 BFS를 타고 1씩 증가시켜주며 파이프들을 방문했다. 그렇게 방문한 파이프의 값들에 대해서 L보다 작은 파이프만 세준다면 그게 답이다.

 

코드

//1953. 탈주범 검거.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.StringTokenizer;

public class 탈주범_검거_1953 {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
	static StringBuilder sb = new StringBuilder();
	
	public static void main(String[] args) throws NumberFormatException, IOException {
		int T = Integer.parseInt(br.readLine());
		for(int t=1;t<=T;t++) {
			st = new StringTokenizer(br.readLine());
			int N = Integer.parseInt(st.nextToken());
			int M = Integer.parseInt(st.nextToken());
			int R = Integer.parseInt(st.nextToken());
			int C = Integer.parseInt(st.nextToken());
			int L = Integer.parseInt(st.nextToken());
			
			int[][] tunnel = new int[N][M];
			for(int i=0;i<N;i++) {
				st = new StringTokenizer(br.readLine());
				for(int j=0;j<M;j++) {
					tunnel[i][j] = Integer.parseInt(st.nextToken());
				}
			}
			
			int[][] visit = new int[N][M];
			bfs(new point(R,C), tunnel, visit);
			
			int count=0;
			for(int i=0;i<N;i++) {
				for(int j=0;j<M;j++) {
					if(visit[i][j]<=L && visit[i][j]!=0 && tunnel[i][j]!=0)count++;
				}
			}
			sb.append("#"+t+" "+count+"\n");
			
		}
		System.out.println(sb.toString());
	}
	
	static void bfs(point start, int[][] tunnel, int[][] visit) {
		int[] di = {0,0,1,-1};
		int[] dj = {1,-1,0,0};
		Map<Integer, int[]> map = new HashMap<>();
		map.put(1, new int[] {0,1,2,3});
		map.put(2, new int[] {2,3});
		map.put(3, new int[] {0,1});
		map.put(4, new int[] {0,3});
		map.put(5, new int[] {0,2});
		map.put(6, new int[] {1,2});
		map.put(7, new int[] {1,3});
		
		visit[start.i][start.j]=1;
		Queue<point> q = new LinkedList<point>();
		q.add(start);
		while(!q.isEmpty()) {
			point now = q.poll();
			int D = tunnel[now.i][now.j];
			for(int d=0;d<map.get(D).length;d++) {
				int nextI = now.i+di[map.get(D)[d]];
				int nextJ = now.j+dj[map.get(D)[d]];
				if(0<=nextI&&nextI<tunnel.length&&0<=nextJ&&nextJ<tunnel[0].length) {
					
					//구조물이 있는가 + 처음 방문하는가
					if(tunnel[nextI][nextJ]!=0 && visit[nextI][nextJ]==0) {
						//연결되어 있는가
						boolean check = false;
						int to = tunnel[nextI][nextJ];
						int nextD;
						if(map.get(D)[d]==0)nextD=1;
						else if(map.get(D)[d]==1)nextD=0;
						else if(map.get(D)[d]==2)nextD=3;
						else nextD=2;
						
						for(int k=0;k<map.get(to).length;k++) {
							if(map.get(to)[k]==nextD)
								check=true;
						}
						
						if(check){
							visit[nextI][nextJ]=visit[now.i][now.j]+1;
							q.add(new point(nextI,nextJ));
						}
					}
				}
			}
		}
	}
	
	static class point{
		int i;
		int j;
		point(int i, int j){
			this.i=i;
			this.j=j;
		}
	}
}
728x90
반응형
SMALL