白駿14503号:ロボット掃除機




問題の説明
2 Dアレイナビゲーションは、
  • によって与えられた条件に従って行われる.
  • 方法
  • 方向のナビゲーションであるため、dx、dy配列が使用される.
  • (x,y)位置からd方向にクリーンアップできるかどうかを決定するための検査方法を実現した.
  • 掃除したのは柱が立っているのとは違います.
  • で片付けた場所は、バックするときに通り抜けることができますが、柱がバックするときにぶつかると入れません.
  • だから掃除のマークを9、柱マークを1にします.
  • pseudocode
    while(true){
    	현재 위치를 청소합니다.
        if(왼쪽을 아직 청소하지 않았다면){
        	왼쪽으로 이동합니다.
            청소한 칸의 개수를 +1합니다.
            방향을 왼쪽으로 설정합니다.
        } else if(4방향 모두 청소할 수 없다면){
        	if(뒤로 움직일 수 있다면){
            	뒤로 갑니다.
            }else{ // 뒤로 갈 수 없다면
            	청소를 종료합니다.
            }
        } else{ // 4방향 모두 청소할 수 없는 경우에서 걸러지지 않았기 때문에 
        		// 현재 위치에서 어딘가 청소할 수 있는 공간이 존재하는 상태입니다.
        	현재 위치에서 방향만 변경시켜 봅니다.
        }
    }
    正解
    import java.util.*;
    
    public class Main {
    	static int[] dx = {-1,0,1,0}; // 북 동 남 서 
    	static int[] dy = {0,1,0,-1};
    	static int N,M,d;
    	static int score = 1;
    	static int[][] board;
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		N = sc.nextInt();
    		M = sc.nextInt();
    		int x = sc.nextInt();
    		int y = sc.nextInt();
    		d = sc.nextInt();
    		board = new int[N][M];
    		for (int i = 0; i < N; i++) {
    			for (int j = 0; j < M; j++) {
    				board[i][j] = sc.nextInt();
    			}
    		}
    		while (true) {
            	// 현재 위치를 청소합니다.
    			board[x][y] = 9;
                // 왼쪽 좌표를 구합니다.
    			int left_x = x+dx[(4+d-1)%4];
    			int left_y = y+dy[(4+d-1)%4];
                // 왼쪽을 아직 청소하지 않았다면
    			if(board[left_x][left_y] == 0) {
                	// 왼쪽으로 갑니다.
    				x = left_x;
    				y = left_y;
    				score++; // 왼쪽으로 움직일 때에만 score를 더합니다. // 그렇기 때문에 가장 처음의 청소가 반영되지 않아 score를 0이 아닌 1부터 시작합니다. 
    				d = (4+d-1)%4; // 바라보는 방향을 왼쪽으로 변경해 줍니다.
    			} else if(!check(x,y,0) && !check(x,y,1) && !check(x,y,2) && !check(x,y,3)) {//4방향 모두 청소할 수 없는 상황입니다.
                    // 뒤쪽 좌표를 구합니다.
    				int back_x = x+dx[(4+d-2)%4];
    				int back_y = y+dy[(4+d-2)%4];
                    
    				if(0<= back_x && back_x < N && 0<= back_y && back_y < M && board[back_x][back_y] != 1 ) { // 뒤쪽으로 이동할 수 있다면 (이미 청소한 구역이라도 상관없습니다)
                    	// 후진합니다.
    					x = back_x;
    					y = back_y;
    				}else { // 후진할 수 없다면
    					break; // 청소를 종료합니다.
    				}
    
    			}else { // 4방향 모두 청소가 불가능한 상황은 아닐 때, 즉 4방향중 청소가 가능한 곳이 존재하는 경우입니다.
    				d = (4+d-1)%4;
    			}
    		}
    		System.out.println(score);
    	}
    	
    	public static boolean check(int x, int y, int d) { // (x,y)에서 d방향으로 이동이 가능한지 확인합니다.
    		if(0<= x+dx[d] && x+dx[d] < N && 0<= y+dy[d] && y+dy[d] < M && board[x+dx[d]][y+dy[d]] == 0) return true;
    		return false;
    	}
    
    	
    }