Today's special moments become memories of tomorrow.

BOJ/삼성 SW 역량테스트

[백준 13460번] 구슬 탈출 2 (java)

lotus lee 2019. 9. 18. 22:25

 

사용한 방법 : BFS

 

빨간 구슬의 위치를 넣는 큐와 파란 구슬의 위치를 넣는 큐 이렇게 두 개의 큐를 생성한다.

각각의 큐에는 기울이기를 통해 움직이고 난 후의 빨간구슬의 위치와 파란구슬의 위치 정보가 들어있다.

 

Queue<Pos> redque = new LinkedList<>();

Queue<Pos> blueque = new LinkedList<>();

 

Pos 클래스는 구슬의 위치(n, m)과 구슬이 해당 위치에 도달했을 때 총 움직인 횟수 move 가 들어간다.

	static class Pos {

		int n, m, move;

		Pos(int n, int m, int move) {
			this.n = n;
			this.m = m;
			this.move = move;
		}
	}

 

한 번 기울이면 구슬은 장애물(벽 혹은 다른 구슬)에 부딪힐 때까지 한칸씩 움직인다.

기울이기를 수행한 후 빨간구슬과 파란구슬이 완전히 멈추면, 두 구슬의 위치를 각각의 큐에 넣는다.

상,하,좌,우 4가지의 방향이 있으므로 4번의 기울이기를 한다.

 

그런데 파란구슬이 구멍에 빠지는 경우에는 움직인 구슬의 위치를 큐에 넣어주면 안된다.

특정 방향으로 기울이기를 수행했을 때 파란구슬이 구멍에 빠지게 된다면, 그 방향으로는 기울이기를 하면 안된다. 파란구슬이 구멍에 빠지는 순간 이미 게임이 실패하기 때문이다.

 

따라서 기울이기를 했을 때, 빨간구슬이 구멍에 빠지더라도 여기서 끝이 아니라 그 이후에 파란구슬이 구멍에 빠지는지를 확인해야한다. 만약 빨간구슬도 구멍에 빠지고, 파란구슬도 구멍에 빠지면 게임 실패이므로 역시 마찬가지로 해당 방향으로 기울이기를 해서는 안된다. 

 

 

한 번 기울기가 끝난 후, 그 사이에 구슬들이 구멍에 빠졌는지 여부는 redflag와 blueflag로 판단한다.

redflag = true이면 빨간구슬이 구멍에 빠졌음을 의미하고, 

blueflag = true이면 파란구슬이 구멍에 빠졌음을 의미한다.

 

  • blueflag=true : 큐에 새로 갱신된 위치를 넣지 않고 다른 방향의 기울이기를 수행한다.

  • redflag=true && blueflag=false : bfs를 종료하고 여태까지 기울이기를 한 횟수가 정답이다.

  • redflag=false && blueflag=false : 빨간 구슬과 파란 구슬 각각의 새로운 위치를 큐에 넣는다.

		if (redflag && !blueflag)
			return redPos.move;

		if (!blueflag) {
			redque.add(redPos);
			blueque.add(bluePos);
		}

 

구슬의 이동후에는 구슬의 이동 전에 원래 구슬위치에 있던 문자 'R'과 'B'를 '.'로 변경한다.

(처음에 이렇게 하지 않아서 반복문이 반복될수록 'R'과 'B'가 난무하게 되는 문제가 생겼음)

if (board[redPos.n][redPos.m] == 'R')
	board[redPos.n][redPos.m] = '.';
if (board[bluePos.n][bluePos.m] == 'B')
	board[bluePos.n][bluePos.m] = '.';

 

 

큐에서 새로운 위치를 꺼낼 때는 빨간 구슬의 기울인 횟수를 체크해서 기울이기를 한 횟수가 10보다 크거나 같으면 반복문을 종료하고 -1을 반환한다.

 

 

전체코드 :