https://www.acmicpc.net/problem/13460
13460번: 구슬 탈출 2
첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B' 로 이루어져 있다. '.'은 빈 칸을 의미하고, '#'은 공이 이동할 수 없는 장애물 또는 벽을 의미하며, 'O'는 구멍의 위치를 의미한다. 'R'은 빨간 구슬의 위치, 'B'는 파란 구슬의 위치이다. 입력되는 모든 보드
www.acmicpc.net
BFS를 이용하여 풀었다.
<JAVA>
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
class Main {
public static void main(String[] args) throws Exception {
class INFO {
int bx;
int by;
int rx;
int ry;
int count;
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N, M;
char map[][] = new char[10][10];
boolean visit[][][][] = new boolean[10][10][10][10];
INFO START = new INFO();
int dy[] = { -1, 1, 0, 0 };
int dx[] = { 0, 0, -1, 1 };
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken(" "));
M = Integer.parseInt(st.nextToken(" "));
for (int y = 0; y < N; ++y) {
map[y] = br.readLine().toCharArray();
for (int x = 0; x < M; ++x) {
if (map[y][x] == 'R') {
START.rx = x;
START.ry = y;
} else if (map[y][x] == 'B') {
START.bx = x;
START.by = y;
}
}
}
Queue<INFO> q = new LinkedList<>();
visit[START.rx][START.ry][START.bx][START.by] = true;
q.add(START);
int result = -1;
while (!q.isEmpty()) {
INFO cur = q.poll();
if (cur.count > 10)
break;
if (map[cur.ry][cur.rx] == 'O' && map[cur.by][cur.bx] != 'O') {
result = cur.count;
break;
}
for (int dir = 0; dir < 4; ++dir) {
int next_ry = cur.ry;
int next_rx = cur.rx;
int next_by = cur.by;
int next_bx = cur.bx;
while (true) {
if (map[next_ry][next_rx] != '#' && map[next_ry][next_rx] != 'O') {
next_rx += dx[dir];
next_ry += dy[dir];
} else {
if (map[next_ry][next_rx] == '#') {
next_rx -= dx[dir];
next_ry -= dy[dir];
}
break;
}
}
while (true) {
if (map[next_by][next_bx] != '#' && map[next_by][next_bx] != 'O') {
next_bx += dx[dir];
next_by += dy[dir];
} else {
if (map[next_by][next_bx] == '#') {
next_bx -= dx[dir];
next_by -= dy[dir];
}
break;
}
}
if (next_bx == next_rx && next_by == next_ry) {
if (map[next_ry][next_rx] != 'O') {
int red_dis = Math.abs(next_rx - cur.rx) + Math.abs(next_ry - cur.ry);
int blue_dis = Math.abs(next_bx - cur.bx) + Math.abs(next_by - cur.by);
if (red_dis > blue_dis) {
next_rx -= dx[dir];
next_ry -= dy[dir];
} else {
next_bx -= dx[dir];
next_by -= dy[dir];
}
}
}
if (visit[next_rx][next_ry][next_bx][next_by] == false) {
visit[next_rx][next_ry][next_bx][next_by] = true;
INFO NEXT = new INFO();
NEXT.bx = next_bx;
NEXT.by = next_by;
NEXT.rx = next_rx;
NEXT.ry = next_ry;
NEXT.count = 1 + cur.count;
q.add(NEXT);
}
}
}
System.out.println(result);
}
}
<C++>
#include <iostream>
#include<queue>
using namespace std;
int N, M;
char map[10][10];
bool visit[10][10][10][10];
struct INFO
{
int bx;
int by;
int rx;
int ry;
int count;
};
INFO START;
int dy[] = { -1,1,0,0 };
int dx[] = { 0,0,-1,1 };
int main()
{
ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
cin >> N >> M;
for (int y = 0; y < N; ++y)
for (int x = 0; x < M; ++x)
{
cin >> map[y][x];
if (map[y][x] == 'R')
{
START.rx = x;
START.ry = y;
}
else if (map[y][x] == 'B')
{
START.bx = x;
START.by = y;
}
}
queue<INFO> q;
visit[START.rx][START.ry][START.bx][START.by] = true;
q.push(START);
int result = -1;
while (!q.empty())
{
INFO cur = q.front();
q.pop();
if (cur.count > 10)
break;
if (map[cur.ry][cur.rx] == 'O' && map[cur.by][cur.bx] != 'O')
{
result = cur.count;
break;
}for (int dir = 0; dir < 4; ++dir)
{
int next_ry = cur.ry;
int next_rx = cur.rx;
int next_by = cur.by;
int next_bx = cur.bx;
while (true)
{
if (map[next_ry][next_rx] != '#' && map[next_ry][next_rx] != 'O')
{
next_rx += dx[dir];
next_ry += dy[dir];
}
else
{
if (map[next_ry][next_rx] == '#')
{
next_rx -= dx[dir];
next_ry -= dy[dir];
}
break;
}
}
while (true)
{
if (map[next_by][next_bx] != '#' && map[next_by][next_bx] != 'O')
{
next_bx += dx[dir];
next_by += dy[dir];
}
else
{
if (map[next_by][next_bx] == '#')
{
next_bx -= dx[dir];
next_by -= dy[dir];
}
break;
}
}
if (next_bx == next_rx && next_by == next_ry)
{
if (map[next_ry][next_rx] != 'O')
{
int red_dis = abs(next_rx - cur.rx) + abs(next_ry - cur.ry);
int blue_dis = abs(next_bx - cur.bx) + abs(next_by - cur.by);
if (red_dis > blue_dis)
{
next_rx -= dx[dir];
next_ry -= dy[dir];
}
else
{
next_bx -= dx[dir];
next_by -= dy[dir];
}
}
}
if (visit[next_rx][next_ry][next_bx][next_by] == false)
{
visit[next_rx][next_ry][next_bx][next_by] = true;
INFO NEXT;
NEXT.bx = next_bx;
NEXT.by = next_by;
NEXT.rx = next_rx;
NEXT.ry = next_ry;
NEXT.count = 1 + cur.count;
q.push(NEXT);
}
}
}
cout << result;
}
'알고리즘 > BOJ' 카테고리의 다른 글
14889. 스타트와 링크 (0) | 2019.10.15 |
---|---|
16235. 나무재테크 (0) | 2019.10.15 |
1717. 집합의 표현 (0) | 2019.10.14 |
1157. 단어 공부 (0) | 2019.10.08 |
4963. 섬의 개수 (0) | 2019.10.07 |