본문 바로가기
알고리즘&자료구조

이코테 - 미로탈출(BFS,DFS)

by do_ng 2021. 1. 29.

- 한 번에 갈 수 있는 최단거리를 구하는 게 목표이므로 BFS를 사용해서 문제를 풀었음

 

내가 짠 코드)

public class Test3 {
	
	// N,M (행,열) 
	static int n;
	static int m;
	// 미로 정보 ( 괴물칸 -> 0 , 괴물없는칸 -> 1) 
	static int[][] mazeInfo;
	// 방문여부 체크 (괴물이 없는 부분칸에서 방문했을경우 -> 1 , 방문안했을경우 -> 0) 
	static int[][] mazeCk;
	// 이동 가능한 방향 검사 순서 (우 -> 하 -> 좌 -> 상) 
	static int[] X = {0,1,0,-1};
	static int[] Y = {1,0,-1,0};
	// 최소 이동한 칸 개수 
	static int count = 0;
	
	// 최단거리로 미로 탈출하기 
	public static void bfs(int startX,int startY) {
		
		Queue<String> q = new LinkedList<>();
		q.offer(""+startX+startY); // 큐에 시작 좌표 넣기 
		
		int x=0,y=0; // 시작 좌표 
		while(!q.isEmpty()) {
			q.poll(); // 큐에서 데이터를 꺼냄
			// 해당 위치에서 최단거리로 가는 방향 검사 
			for(int i=0;i<4;i++) {
				int x1 = x + X[i];
				int y1 = y + Y[i];
				// 미로의 크기에서 벗어나는지 검사 
				if(x1 < 0 || x1 >= n || y1 < 0 || y1 >= m) continue;
				// 괴물칸이 아니고 방문여부가 없으면 캐릭터 이동시킨후 for문 탈출 
				if(mazeCk[x1][y1] == 0 && mazeInfo[x1][y1] == 1) {
					mazeCk[x1][y1] = 1; // 방문처리 
					x = x1;
					y = y1;
					q.offer(""+x+y); // 큐에 이동한 좌표 넣기 
					count++; // 칸이동 
					break;
				}
			}
			// 출구칸에 도착할 경우 
			if(x == n-1 && y == m-1){
				count++;
				break;
			}
		}
		
	}
	
	public static void main(String[] args){
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		try {
			// readLine()의 경우 Enter가 입력되기 전까지 문자열을 입력받음 
			String[] nums = br.readLine().split(" "); // 입력받은 문자들을 공백단위로 구분해서 문자열 배열에 넣어줌 
			n = Integer.parseInt(nums[0]);
	        m = Integer.parseInt(nums[1]);
			mazeInfo = new int[n][m];
			mazeCk = new int[n][m];
			
			// 미로 정보 입력 
			for(int i=0;i<n;i++) {
				String[] temp = br.readLine().split(""); // 공백없이 붙어서 입력함 
				for(int j=0;j<m;j++) {
					mazeInfo[i][j] = Integer.parseInt(temp[j]);
				}
			}

			// 최단거리로 미로탈출하는 메서드 호출
			bfs(0,0);
			
			System.out.println(count);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

 

다른 코드)

class Nodes{

    private int x;
    private int y;

    public Nodes(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return this.x;
    }
    
    public int getY() {
        return this.y;
    }
}
// 이코테 - 미로 탈출 
public class Main {
	
	// N,M (행,열) 
	static int n,m;
	// 미로 정보 ( 괴물칸 -> 0 , 괴물없는칸 -> 1) 
	static int[][] mazeInfo;
	// 이동 가능한 방향 검사 순서 (우 -> 하 -> 좌 -> 상) 
	static int[] X = {0,1,0,-1};
	static int[] Y = {1,0,-1,0};
	
	// 최단거리로 미로 탈출하기 
	public static int bfs(int startX,int startY) {
		
		Queue<Nodes> q = new LinkedList<>();
		q.offer(new Nodes(startX,startY)); // 큐에 시작 좌표 넣기 
		
		while(!q.isEmpty()) {
			Nodes node = q.poll(); // 큐에서 데이터를 꺼냄
			startX = node.getX();
			startY = node.getY();
			// 해당 위치에서 최단거리로 가는 방향 검사 (4가지 방향중 최단거리로 가는 방향)  
			for(int i=0;i<4;i++) {
				int x1 = startX + X[i];
				int y1 = startY + Y[i];
				// 미로의 크기에서 벗어나는지 검사 
				if(x1 < 0 || x1 >= n || y1 < 0 || y1 >= m) continue;
				// 괴물칸인 경우 
				if(mazeInfo[x1][y1] == 0) continue;
				// 처음 방문하는 칸일경우 최단 거리 기록하고 for문을 빠져나감
				if(mazeInfo[x1][y1] == 1) {
					mazeInfo[x1][y1] = mazeInfo[startX][startY] + 1;
					q.offer(new Nodes(x1,y1)); // 큐에 이동한 좌표 넣기  
					break; // 첫번째 시작위치가 다시 방문될 가능성이 있기때문에 break 구문으로 빠져나가줌
				}
			}
		}
		
		// 출구까지의 최단 거리 반환 
		return mazeInfo[n-1][m-1];
	}
	
	public static void main(String[] args){
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		try {
			// readLine()의 경우 Enter가 입력되기 전까지 문자열을 입력받음 
			String[] nums = br.readLine().split(" "); // 입력받은 문자들을 공백단위로 구분해서 문자열 배열에 넣어줌 
			n = Integer.parseInt(nums[0]);
	        m = Integer.parseInt(nums[1]);
			mazeInfo = new int[n][m];
			
			// 미로 정보 입력 
			for(int i=0;i<n;i++) {
				String[] temp = br.readLine().split(""); // 공백없이 붙어서 입력함 
				for(int j=0;j<m;j++) {
					mazeInfo[i][j] = Integer.parseInt(temp[j]);
				}
			}

			// 최단거리로 미로탈출하는 메서드 호출
			System.out.println(bfs(0,0));
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

 

푸는 방법은 맞았지만 쓸데없는 여러 변수의 선언으로 메모리 공간을 낭비하고 있는 점에 대해서 주의하자

메모리 공간을 아끼기 위해서 최대한 변수를 적게 쓰는게 더 좋음 (***) 

 

클래스를 따로만들어서 사용하는 것으로 코드 상의 간결함? 줄 수 있는 거 같음 (*)

 

본격적으로 코드를 작성하기 전에 필요한 변수들을 먼저 선언해놓고 헷갈릴수 있으니 주석처리를 해놓는 습관을 가지자(**) 

'알고리즘&자료구조' 카테고리의 다른 글

정렬(Sort)  (0) 2021.01.30
백준 - 1926(BFS,DFS)  (0) 2021.01.30
이코테 - 음료수 얼려 먹기(DFS)  (0) 2021.01.27
BFS,DFS  (0) 2021.01.27
재귀함수 - 팩토리얼  (0) 2021.01.26