백준/구현

14503 로봇 청소기

have a good time 2024. 6. 22. 11:36
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;


class Position{
	
	int x;
	int y;
	
	Position(int x, int y) {
		
		this.x = x;
		this.y = y;
		
	}
}

public class Main {	
	
	static int map[][];	
	static boolean clean[][];	
	static int N;
	static int M;	
	static int r;
	static int c;
	static int d;
	static int count;
	
	public static void main(String[] args) throws IOException {		
	
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		
		st = new StringTokenizer(br.readLine(), " ");
		r = Integer.parseInt(st.nextToken());
		c = Integer.parseInt(st.nextToken());
		d = Integer.parseInt(st.nextToken());	
		
		map = new int [N][M];
		clean = new boolean[N][M];
		count = 0;
		
		for(int i=0; i<N; i++) {			
			st = new StringTokenizer(br.readLine(), " ");
			
			for(int j=0; j<M; j++) {					
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}	
		
		solve(r,c,d);
		System.out.println(count);		
		
	}
	
	public static void solve(int a, int b,int direction) {	
		
		// 1) 현재칸이 청소되지 않았다면 현재 칸 청소.
		// 벽이 아닌 곳 
		if(!clean[a][b] && map[a][b]==0) {
		
			clean[a][b] = true;
			count++;
		}
		
		// 2) 현재 칸 주변 4칸 중 청소되지 않은 곳이 있는지 여부 
		int dx[] = {-1,1,0,0};
		int dy[] = {0,0,-1,1};
		boolean flag = true;
		
		for(int i=0; i<4; i++) {
			
			int nx = a + dx[i];
			int ny = b + dy[i];
			
			// 청소 안 되어 있는지 확인 
			// flag= false : 한 곳이라도 청소 안 된 곳이 있음 
			if(!clean[nx][ny] && map[nx][ny]==0 ) {				
				flag = false;
				
			}
		}
			
		// 2-1) 청소가 모두됨
		if(flag) {		
		
			int nextA =0;
			int nextB =0;
			
			// 후진
			Position p = goBackward(a, b, direction);
			
			nextA = p.x;
			nextB = p.y;
			
			// 후진 가능할 때,
			if(nextA>=0 && nextA<N && nextB>=0 && nextB<M && map[nextA][nextB]==0) {
			
				// 후진 후 1번으로 돌아감.
				solve(nextA,nextB,direction);
			
			//후진 불가능
			}else {
				
				// 청소기 작동 멈춤. 			
				return;
			}
			
			
		// 2-2) 청소 안 된 빈 칸 있음. 
		}else {
		
			// 반시계방향으로 90도 회전 	
			direction = rotate(direction);		
			
			int nextA = 0;
			int nextB = 0;
			
			// 한 칸 앞 위치
			Position p =moveForward(a,b,direction);
			nextA = p.x;
			nextB = p.y;
		
			// 한 칸 앞이 청소되지 않은 빈 칸인 경우 한 칸 전진
			if(nextA >=0 && nextA <N && nextB >=0 && nextB <M &&!clean[nextA][nextB] && map[nextA][nextB]==0) {
					
				// 1번으로 돌아감. 
				solve(nextA, nextB, direction);					
						
			// 한 칸 앞이 청소되지 않은 빈 칸이 아닌 경우
			}else {
			
				// 한 칸 전진 안 하고 1번으로 돌아감. 
				solve(a,b,direction);
			
			}			
		}		
	}
	
	// 후진
	public static Position goBackward(int a, int b, int direction) {
		
		int x =0;
		int y= 0;		
		
		//북쪽을 바라본다면 -> 남쪽 방향으로 이동
		if(direction == 0) {			
			
			x = a+1;
			y = b;
			
			
		//동쪽 -> 서쪽
		}else if(direction ==1) {
			
			x = a;
			y = b-1;
			
			
		//남쪽 -> 북쪽
		}else if(direction ==2) {
			
			x = a-1;
			y = b;
			
		//서쪽 -> 동쪽
		}else if(direction ==3) {
			
			x = a;
			y = b+1;				
		}
		
		Position p = new Position(x,y);		
		return p;
	}
	
	
	// 한 칸 앞 전진
	public static Position moveForward(int a, int b, int direction) {
		
		int x=0;
		int y=0;
		
		//북쪽을 바라볼 때 한 칸 전진
		if(direction ==0) {
			
			x = a-1;
			y = b;
			
			
		// 동쪽
		}else if(direction ==1) {
			
			x = a;
			y = b+1;
			
		// 남쪽
		}else if(direction ==2) {
			
			x = a+1;
			y = b;
			
		//서쪽
		}else if(direction ==3) {
			
			x = a;
			y = b-1;
		}	
		
		Position  p = new Position(x,y);
		return p;
		}
	
	
	// 반 시계 방향으로 90도 회전
	public static int rotate(int direction) {
		
		//북쪽 ->서쪽 
		if(direction == 0) {				
			direction = 3;		
			
		// 동쪽 -> 북쪽
		}else if (direction == 1) {
			direction = 0;			
			
		// 남쪽 -> 동쪽
		}else if(direction == 2) {				
			direction = 1;
			
		// 서쪽 -> 남쪽
		}else if(direction ==3) {				
			direction = 2;
			
		}
		
		return direction;
	}
	
}