SWEA_탈주범검거_1953

2020. 5. 21. 21:33 from CS/Algorithm

1. 과정

- 현재 칸에서 갈 수 있는 방향과, 다음 칸에서 현재칸을 받을 수 있는지 확인하는것이 이 문제의 핵심이다.

- 크게 어려울것 없는 bfs 응용 문제이다.

 

2. 구현

언어 : JAVA

메모리 : 27,668 kb

실행시간 : 152 ms

import java.io.*;
import java.util.*;

public class SWEA_탈주범검거_1953_O {
	static int R, C, sr, sc, L, answer;
	static int[][] map;
	static int[] dr = { -1, 1, 0, 0 };
	static int[] dc = { 0, 0, -1, 1 };
	static boolean[][] visit;

	static class Pair {
		int r, c;

		public Pair(int r, int c) {
			this.r = r;
			this.c = c;
		}
	}

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		for (int testCase = 1; testCase <= T; ++testCase) {
			String[] s = br.readLine().split(" ");
			R = Integer.parseInt(s[0]);
			C = Integer.parseInt(s[1]);
			sr = Integer.parseInt(s[2]);
			sc = Integer.parseInt(s[3]);
			L = Integer.parseInt(s[4]);
			map = new int[R][C];
			visit = new boolean[R][C];
			for (int i = 0; i < R; ++i) {
				s = br.readLine().split(" ");
				for (int j = 0; j < C; ++j) {
					map[i][j] = Integer.parseInt(s[j]);
				}
			}
			solve();
			System.out.println("#" + testCase + " " + answer);
		}
	}

	private static void solve() {
		Queue<Pair> q = new LinkedList<>();
		q.add(new Pair(sr, sc));
		visit[sr][sc] = true;
		answer = 1;
		ArrayList<Integer> checkList = new ArrayList<Integer>();
		// level로 최대 L초까지 계산한다.
		int level = 1;
		while (!q.isEmpty()) {
			// 현재 레벨과 L과 같으면 탈출
			if(level==L)
				break;
			int qSize = q.size();
			for (int k = 0; k < qSize; ++k) {
				Pair p = q.poll();
				int r = p.r;
				int c = p.c;
				int hallNum = map[r][c];
				checkList.clear();
				// 터널 번호에 따라서 그 방향만 탐색한다.
				switch (hallNum) {
				case 0:
					break;
				case 1:
					checkList.add(0);
					checkList.add(1);
					checkList.add(2);
					checkList.add(3);
					break;
				case 2:
					checkList.add(0);
					checkList.add(1);
					break;
				case 3:
					checkList.add(2);
					checkList.add(3);
					break;
				case 4:
					checkList.add(0);
					checkList.add(3);
					break;
				case 5:
					checkList.add(1);
					checkList.add(3);
					break;
				case 6:
					checkList.add(1);
					checkList.add(2);
					break;
				case 7:
					checkList.add(0);
					checkList.add(2);
					break;
				}
				int tr, tc;
				for (int i = 0; i < checkList.size(); ++i) {
					int dir = checkList.get(i);
					tr = r + dr[dir];
					tc = c + dc[dir];
					if (tr < 0 || tc < 0 || tr >= R || tc >= C || visit[tr][tc])
						continue;
					// 다음칸에서 받을 수 있는지 체크해야한다.
					// 예를들어 dir==0이면 상 방향이므로 윗칸 입장에서는 아랫쪽으로 터널이 나 있어야 한다.
					if (dir == 0 && (map[tr][tc] == 1 || map[tr][tc] == 2 || map[tr][tc] == 5 || map[tr][tc] == 6)) {
						q.add(new Pair(tr, tc));
						visit[tr][tc] = true;
						answer++;
					} else if (dir == 1
							&& (map[tr][tc] == 1 || map[tr][tc] == 2 || map[tr][tc] == 4 || map[tr][tc] == 7)) {
						q.add(new Pair(tr, tc));
						visit[tr][tc] = true;
						answer++;
					} else if (dir == 2
							&& (map[tr][tc] == 1 || map[tr][tc] == 3 || map[tr][tc] == 4 || map[tr][tc] == 5)) {
						q.add(new Pair(tr, tc));
						visit[tr][tc] = true;
						answer++;
					} else if (dir == 3
							&& (map[tr][tc] == 1 || map[tr][tc] == 3 || map[tr][tc] == 6 || map[tr][tc] == 7)) {
						q.add(new Pair(tr, tc));
						visit[tr][tc] = true;
						answer++;
					}
				}
			}
			level++;
		}
	}
}

'CS > Algorithm' 카테고리의 다른 글

BOJ_Gaaaaaaaaaarden_18809  (0) 2020.05.24
SWEA_벽돌깨기_5656  (0) 2020.05.23
SWEA_미생물격리_2382  (0) 2020.05.21
SWEA_무선충전_5644  (0) 2020.05.21
SWEA_프로세서연결하기_1767  (0) 2020.05.21
Posted by Jyoel :