본문 바로가기
Algorithm/Baekjoon

Baekjoon 16441 아기돼지와 늑대 JAVA

by Hunveloper 2022. 5. 17.
728x90
 

16441번: 아기돼지와 늑대

첫 번째 줄에는 격자의 행의 수를 나타내는 N (3 ≤ N ≤ 100) 과 격자의 열의 수를 나타내는 M (3 ≤ M ≤ 100) 이 주어집니다. 두 번째 줄부터 N개의 줄에 지도의 정보를 나타내는 길이가 M인 문자열

www.acmicpc.net

문제

산으로 둘러싸인 고리분지에 사는 아기돼지 삼형제는 엄마돼지로부터 독립하여 새 집을 지으려 합니다.

고리분지는 N × M 크기의 2차원 격자로 나타낼 수 있고 각 칸의 지형은 초원, 빙판, 산 중 하나입니다.

고리분지에는 돼지가족들 뿐만 아니라 늑대들도 살고 있습니다. 늑대는 상하좌우 인접한 칸 중 산이 아닌 칸으로 이동할 수 있습니다. 만약 이동한 칸이 빙판이라면 초원을 밟거나 산에 부딪칠 때까지 이동한 방향으로 미끄러집니다. 산에 부딪친 경우 늑대는 빙판 위에 가만히 서있을 수 있고 다시 다른 방향으로 이동할 수 있습니다.

게으른 아기돼지들은 지푸라기로 집을 지을 예정이기 때문에 늑대가 집이 있는 칸에 도착하기만 한다면 손쉽게 침입할 수 있습니다. 고리분지에 사는 늑대들이 도달할 수 없고 지형이 초원인 칸을 '안전한 곳'이라고 부릅니다. 게으른 아기돼지들을 위해 고리분지의 지도가 주어지면 지도 위에 모든 안전한 곳의 위치를 표시해주세요.

 
입력

첫 번째 줄에는 격자의 행의 수를 나타내는 N (3 ≤ N ≤ 100) 과 격자의 열의 수를 나타내는 M (3 ≤ M ≤ 100) 이 주어집니다.

두 번째 줄부터 N개의 줄에 지도의 정보를 나타내는 길이가 M인 문자열들이 주어집니다. 

i+1번째 줄의 j번째 문자는 i번째 행 j번째 열의 지형 종류를 의미하며 '.' 일 경우 초원, '+' 일 경우 빙판, '#' 일 경우 산, 그리고 'W'는 늑대가 살고 있음을 나타냅니다. 늑대가 사는 칸은 여러 개일 수 있고 늑대가 사는 지형은 항상 초원입니다. 지도의 첫 번째, N번째 행과 첫 번째, M번째 열은 항상 산입니다.

출력

입력으로 주어진 지도를 출력하되 아기돼지가 살 수 있는 초원은 문자 'P'로 대체하여 출력합니다.

풀이

코드 참고

코드
import java.util.*;
import java.io.*;

public class Main {
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n=Integer.parseInt(st.nextToken()), m=Integer.parseInt(st.nextToken());
		char [][] map = new char [n][m];
		boolean [][] pigs = new boolean [n][m], isVisited = new boolean[n][m];	// pigs배열은 가능성이 있는 위치를 true로 설정
		Queue<int[]> q = new LinkedList<int[]>();
		for(int i=0;i<n;i++) {
			String str = br.readLine();
			for(int j=0;j<m;j++) {
				map[i][j]=str.charAt(j);
				if(map[i][j]=='W')
					q.add(new int[] {i,j});
				else if(map[i][j]=='.')
					pigs[i][j]=true;
			}
		}
		int [] dx = {-1,1,0,0}, dy= {0,0,1,-1};
		while(q.size()>0) {
			int [] cur = q.poll();
			int x=cur[0], y=cur[1];
			isVisited[x][y]=true;
			
			for(int i=0;i<4;i++) {
				if(x+dx[i]>=0 && x+dx[i]<n && y+dy[i]>=0 && y+dy[i]<m) {
					// 산이라서 탐색 불가능
					if(map[x+dx[i]][y+dy[i]]=='#')
						continue;
					// 초원이거나 늑대가 있는 자리거나, 동시에 한번도 방문하지 않은 위치면 탐색
					else if((map[x+dx[i]][y+dy[i]]=='.' || map[x+dx[i]][y+dy[i]]=='W') && !isVisited[x+dx[i]][y+dy[i]]) {
						q.add(new int[] {x+dx[i], y+dy[i]});
						isVisited[x+dx[i]][y+dy[i]]=true;
						pigs[x+dx[i]][y+dy[i]]=false;	// 만약 초원이었다면 늑대가 탐색 가능한 지역이기에 돼지는 살지 못함
					}
					else if(map[x+dx[i]][y+dy[i]]=='+') {	// 빙판이라면 미끄러져서 산에 막히거나 초원까지 가야함
						int j=1;
						while(map[x+dx[i]*j][y+dy[i]*j]=='+') {	// 미끄러지기
							j++;
						}
						// 미끄러지기가 끝난 상태는 벽에 막혀서 끝나거나 초원에 도착한 경우임
						
						// 벽에 막힌 상태   W+++# 위아래로 움직일 수 있음
						// 미끄러져서 도착했다면 그 위치로부터 지나온 방향에 수직으로 탐색이 다시 가능
						// 현재 위치는 얼음이 끝난 다음 위치이기에 이동방향을 한칸 뒤로가서 큐에 삽입
						if(map[x+dx[i]*j][y+dy[i]*j]=='#' && !isVisited[x+dx[i]*(j-1)][y+dy[i]*(j-1)]) {
							q.add(new int[] {x+dx[i]*(j-1), y+dy[i]*(j-1)});
							isVisited[x+dx[i]*(j-1)][y+dy[i]*(j-1)]=true;
						}
						// 다 미끄러지고 초원  W+++. 초원부터 움직임
						// 얼음에 다 미끄러지고 초원에 도착했기에 4방탐색이 가능해짐
						// 동시에 늑대가 탐색을 했기에 돼지는 거주불가능
						if(map[x+dx[i]*j][y+dy[i]*j]=='.' && !isVisited[x+dx[i]*j][y+dy[i]*j]) {
							q.add(new int[] {x+dx[i]*j, y+dy[i]*j});
							isVisited[x+dx[i]*j][y+dy[i]*j]=true;
							pigs[x+dx[i]*j][y+dy[i]*j]=false;
						}
					}
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				if(pigs[i][j])	// 처음에 초원 위치에서 늑대가 탐색하지 않은 경로라면 P를 출력
					bw.write('P');
				else
					bw.write(map[i][j]);
			}
			bw.write("\n");
		}
		bw.close();
	}
}

 

728x90
728x90

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

Baekjoon 2193 이친수 JAVA  (0) 2022.05.17
Baekjoon 2467 용액 JAVA  (0) 2022.05.17
Baekjoon 15947 아기 석환 뚜루루 뚜루 JAVA  (0) 2022.05.15
Baekjoon 3568 iSharp JAVA  (0) 2022.05.13
Baekjoon 10569 다면체 JAVA  (0) 2022.05.10

댓글