SWEA 모의역량테스트 탈주범 검거

2020. 6. 2. 22:39프로그래밍 대회



현재 터널 상태 : p 
다음 터널 상태: n 
p와 n으로 갈 수있는지 여부 판단 가능 
온방향 상 
in 
p -> n 
1-> 1,2,5,6 
2-> 1,2,5,6
4-> 1,2,5,6
7-> 1,2,5,6
온방향 하
p -> n
1-> 1,2,4,7
2
5
6
온방향 좌
p -> n
1-> 1,3,4,5
3
6
7
온방향 우
p -> n
1-> 1,3,6,7
3
4
5

0   1   2  3

상 좌 하 우 로 배치하여 

(d+2)%4 를 하면 반대 방향을 바로 가르키도록 하였다.

상: 0 

(0+2)%4 = 2 : 하 

 

소스 코드 
 

import java.util.*;
import java.io.*;
public class Solution {


	static int[][] directions;
	static int[][] dirs= {{-1,0} ,{0,-1}, {1,0}, {0,1}}; //상  좌 하 우
	static int N,M,R,C,L;
	static boolean [][] v;
	static int [][] map;
	static class Point{
		int x,y,t;

		public Point(int x, int y, int t) {
			super();
			this.x = x;
			this.y = y;
			this.t = t;
		}
	}
	public static void main(String[] args) throws NumberFormatException, IOException {
		directions= new int[][]{
			{1,2,4,7}, //상
			{1,3,6,7}, //좌
			{1,2,5,6}, //하
			{1,3,4,5} // 우
			}; 
//		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		BufferedReader bf = new BufferedReader(new StringReader(src));
		int T= Integer.parseInt(bf.readLine());
		StringTokenizer st;
		StringBuilder sb= new StringBuilder();
		for (int testcase = 1; testcase <= T; testcase++) {
			st=new StringTokenizer(bf.readLine());
			N= Integer.parseInt(st.nextToken());
			M= Integer.parseInt(st.nextToken());
			R= Integer.parseInt(st.nextToken());
			C= Integer.parseInt(st.nextToken());
			L= Integer.parseInt(st.nextToken());
			map= new int[N][M];
			v =new boolean[N][M];
			for (int i = 0; i < N; i++) {
				st =new StringTokenizer(bf.readLine());
				for (int j = 0; j < M; j++) {
					map[i][j]=Integer.parseInt(st.nextToken());
				}
			}
			bfs();
			int cnt=0;
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < M; j++) {
					if(v[i][j]) cnt++;
				}
			}
			sb.append("#"+testcase+" ");
			sb.append(cnt+"\n");//답 
			
		}
		System.out.println(sb);
		
		
	}
	private static void bfs() {
		// 맨홀 뚜껑  위치에서 시작 
		Queue<Point> q =new LinkedList<>();
		
		q.add(new Point(R,C,1));
		v[R][C]=true;
		
		while(!q.isEmpty()) {
			Point pos=q.poll();
			if(pos.t==L) break;
			for (int d = 0; d < dirs.length; d++) {
				int x = pos.x+dirs[d][0];
				int y = pos.y+dirs[d][1];
				if(!IsIn(x,y)) continue; 
				if(v[x][y]) continue; // 간곳은 다시 안감 
				if(matchingdirs(map[pos.x][pos.y],d,map[x][y])) {// true 면 가려는방향= 뚤린방향 , 뚤린 방향의 반대가 받는방향
					q.add(new Point(x,y,pos.t+1));
					v[x][y]=true;
				}
			}
			
		}
	}
	
	private static boolean matchingdirs(int present, int d,int next) {
		for (int i = 0; i < directions[d].length; i++) {
			//현재 내가 뚫린 방향과 가려는 방향이 일치하나
			if(directions[d][i]==present) { // 안에 present 가 있냐  
				// 일치하면 present 방향과 next가 일치하나  
				//  0 1 2 3 0 +2 %4
				 // 상 좌  하  우  
				int reverse =(d+2)%4;
				for (int j = 0; j < directions[reverse].length; j++) {
					if(directions[reverse][j] == next) return true;
				}
			}
		}
		return false;
	}
	private static boolean IsIn(int x, int y) {
		return 0<=x && x<=N-1 && 0<=y && y<=M-1 ;
	}
	static String src="1\r\n" + 
			"5 6 2 2 6\r\n" + 
			"3 0 0 0 0 3\r\n" + 
			"2 0 0 0 0 6\r\n" + 
			"1 3 1 1 3 1\r\n" + 
			"2 0 2 0 0 2\r\n" + 
			"0 0 4 3 1 1\r\n";
}

'프로그래밍 대회' 카테고리의 다른 글

백준 괄호 9093 java  (0) 2022.03.17
1757 달려달려 (java)  (0) 2020.08.05
백준 2636 치즈  (0) 2020.05.15
2630 색종이 만들기  (0) 2020.02.25
2178 미로탐색  (0) 2020.02.25