코딩테스트

[Programmers/JAVA] 거리두기 확인하기

Eun 2022. 4. 16. 22:41

https://programmers.co.kr/learn/courses/30/lessons/81302?language=java 

 

코딩테스트 연습 - 거리두기 확인하기

[["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], ["POOPX", "OXPXP", "PXXXO", "OXXXO", "OOOPP"], ["PXOPX", "OXOXP", "OXPOX", "OXXOP", "PXPOX"], ["OOOXX", "XOOOX", "OOOXX", "OXOOX", "OOOOO"], ["PXPXP", "XPXPX", "PXPXP", "XPXPX", "PXPXP"]] [1, 0, 1, 1, 1]

programmers.co.kr

풀이

 

해당 문제는 응시자가 앉아있는 위치에서 가까운 곳부터 탐색해야하기 때문에 BFS를 이용하여 문제를 풀었다.

(아직 능숙하게 풀기에는 멀은 것 같다 ...ㅠ)

 

1. 응시자(P)가 앉아있는 위치를 찾는다.

2. 응시자의 위치부터 탐색한다.

3. 응시자 인근 2이하에 P가 있으면 false,

- 파티션(X)가 있다면 더이상 보지않고 패스! (거리두기 성공)

- 빈테이블(O)가 있다면 빈테이블부터 다시 탐색시작! 맨해튼거리가 2보다 작은 것만 탐색한다. (그 이후는 거리두기 성공)

 

정리를 하자면

➡️ 응시자에서부터 맨해튼거리가 1인곳에 P가 없고, 맨해튼거리가 2인 곳에 O가 오고, O로 부터 맨해튼거리가 1인 곳에 P가 없다면 true를 반환하여 1을 저장한다. 

 

코드

class Solution {
	
	int[] dx = {1,-1,0,0};
	int[] dy = {0,0,-1,1};
	
    public int[] solution(String[][] places) {
        int[] answer = new int[places.length];
        
        for(int i=0;i<places.length;i++) {
        	// 거리두기 성공 여부저장
        	answer[i]=isTrue(places[i]);
        }
        return answer;
    }
    
    public int isTrue(String[] map) {
    	for(int i=0;i<map.length;i++) {
    		for(int j=0;j<map[i].length();j++) {
    			if(map[i].charAt(j)=='P') {
    				if(!bfs(map, i,j)) return 0;	// 거리두기 실패
    			}
    		}
    	}
    	return 1;
    }
    
    public boolean bfs(String[] map, int x, int y) {
    	Queue<Node> q = new LinkedList<>();
    	boolean[][] visited = new boolean[map.length][map.length];
    	q.offer(new Node(x,y));
    	visited[x][y]=true;
    	
    	while(!q.isEmpty()) {
    		Node node = q.poll();
    		
    		for(int i=0;i<4;i++) {
    			int new_x = node.x+dx[i];
    			int new_y = node.y+dy[i];
    			int manhattan = Math.abs(x-new_x) + Math.abs(y-new_y);
    			
    			if(new_x < 0 || new_y < 0 || new_x >= map.length || new_y >= map.length) continue;
    			// 범위를 벗어났을 때
    			if(visited[new_x][new_y] || manhattan > 2) continue;
    			// 방문했거나 맨해튼거리가 3이상이면 패스
    			
    			visited[new_x][new_y] = true;
    			if(map[new_x].charAt(new_y)=='X') continue;
    			// 파티션있으면 패스
    			else if(map[new_x].charAt(new_y)=='P') return false;
    			// 응시자가 있으면 거리두기 실패
    			else q.offer(new Node(new_x, new_y));
    			// 빈테이블이 있으면 다시 탐색시작!
    		}
    	}
    	return true;
    }
    
    public class Node {
    	int x;
    	int y;
    	
    	public Node(int x, int y) {
    		this.x=x;
    		this.y=y;
    	}
    }
}

'코딩테스트' 카테고리의 다른 글

[BOJ_1074/JAVA] Z  (0) 2022.04.19
[BOJ_7576/JAVA] 토마토  (0) 2022.04.17
[BOJ_2565/JAVA] 전깃줄  (0) 2022.04.12
[BOJ_14888/JAVA] 연산자 끼워 넣기  (0) 2022.02.11
[BOJ_18405/JAVA] 경쟁적 전염  (0) 2022.02.07