예전에 알고리즘 수업시간에 테세우스 게임 알고리즘과 비슷하게 풀었음! (DFS - 백트래킹)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
class Main {
static String map[][];
static int red_x=0,red_y=0,blue_x=0,blue_y=0,out_x=0,out_y=0;
static int result=Integer.MAX_VALUE;
static int index=-1;
static int check[][][][];
// static ArrayList<Integer>visit_bx=new ArrayList<Integer>();
static int visit_bx[]=new int[11];
static int visit_by[]=new int[11];
static int visit_x[]=new int[11];
static int visit_y[]=new int[11];
static int cal=0,row=0;
public static void main(String[] args) throws IOException{
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer token=new StringTokenizer(reader.readLine());
cal=Integer.parseInt(token.nextToken());
row=Integer.parseInt(token.nextToken());
map=new String[cal][row];
String s;
for(int i=0;i<cal;i++){
s=reader.readLine();
for(int j=0;j<row;j++){
map[i][j]=String.valueOf(s.charAt(j));
if(map[i][j].equals("R")){
red_x=j;
red_y=i;
}else if(map[i][j].equals("B")){
blue_x=j;
blue_y=i;
}else if(map[i][j].equals("O")){
out_x=j;
out_y=i;
}
}
}
check=new int [cal][row][cal][row];
move();
if(result==Integer.MAX_VALUE){
System.out.println("-1");
}else if(result>10){
System.out.println("-1");
}else{
System.out.println(result);
}
}
static boolean promising(int y, int x, int by, int bx){
if(check[y][x][by][bx]!=1){
//이동한 좌표가 이미 갔던 곳이아라면 ( 갔던 곳이면무한반복생길 수 있다)
red_y=y;
red_x=x;
return true;
}
return false;
}
static void move(){
boolean stop=false;
index++;
if(index<10){//10번이상이면 의미가없다.
visit_x[index]=red_x; //back했을떄 다시 초기화해줄 좌표 저장
visit_y[index]=red_y;
visit_bx[index]=blue_x; //back했을떄 다시 초기화해줄 좌표 저장
visit_by[index]=blue_y;
check[red_y][red_x][blue_y][blue_x]=1; //방문표시
/* blue up */
for(int j=blue_y-1;j>=0 ;j--){
if(map[j][blue_x].equals("#")){ //벽을 만났는데
if(red_x==blue_x && red_y<blue_y && j<red_y){
//B위에 R이있고, R이 j보다 아래에 있으면
blue_y=j+2;
}else{
blue_y=j+1;
}
break;//가장 처음만나는 벽에서 멈춘다.
}else if(map[j][blue_x].equals("O")){
stop=true;
break;
}
}
/* red up */
for(int j=red_y-1;j>=0&&stop==false;j--){
if(map[j][red_x].equals("#")){ //벽을 만났는데
if(red_x==visit_bx[index] && red_y>visit_by[index] && j<visit_by[index]) {
//R위에 B가 있었으면 B공간을 남긴다. && 둘사이에 그 벽이 없어야함!
if(promising(j+2,red_x,blue_y,blue_x)){
move();
}
}else{
if(promising(j+1,red_x,blue_y,blue_x)){
move();
}
}
break;//가장 처음만나는 벽에서 멈춘다.
}else if(map[j][red_x].equals("O")){ //
result=Math.min(result,index+1);
break;
}
}
red_x=visit_x[index];
red_y=visit_y[index];
blue_x=visit_bx[index];
blue_y=visit_by[index];
stop=false;
/* blue down */
for(int j=blue_y+1;j<cal ;j++){
if(map[j][blue_x].equals("#")){ //벽을 만났는데
if(red_x==blue_x && red_y>blue_y && j>red_y){//B아래 R이있으면
blue_y=j-2;
}else{
blue_y=j-1;
}
break;
}else if(map[j][blue_x].equals("O")){
stop=true;
break;
}
}
/* red down */
for(int j=red_y+1;j<cal&&stop==false;j++){
if(map[j][red_x].equals("#")){ //벽을 만났는데
if(red_x==visit_bx[index] && red_y<visit_by[index] && j>visit_by[index]){
//같은 x좌표 위에 B의 y가 R보다 아래일때(아래일수록 좌표 증가)
// 아래로 이동하게 되면 B도 같이 이동하게 되어 B의 공간을 비워야한다.
if(promising(j-2,red_x,blue_y,blue_x)){
move();
}
}else{
if(promising(j-1,red_x,blue_y,blue_x)){
move();
}
}
break;
}else if(map[j][red_x].equals("O")){
result=Math.min(result,index+1);
break;
}
}
red_x=visit_x[index];
red_y=visit_y[index];
blue_x=visit_bx[index];
blue_y=visit_by[index];
stop= false;
/* blue right */
for(int j=blue_x+1;j<row ;j++){
if(map[blue_y][j].equals("#")){ //벽을 만났는데
if(red_y==blue_y && red_x>blue_x && j>red_x){
//B오른쪽에 R이있으면 && 벽(j)이 red보다 오른쪽에있으면
blue_x=j-2;
}else{
blue_x=j-1;
}
break;
}else if(map[blue_y][j].equals("O")){
stop=true;
break;
}
}
/* red right */
for(int j=red_x+1;j<row&&stop==false;j++){
if(map[red_y][j].equals("#")){ //벽을 만났는데
if(red_y==visit_by[index] && red_x<visit_bx[index]&& j>visit_bx[index]){
if(promising(red_y,j-2,blue_y,blue_x)){
move();
}
}else{
if(promising(red_y,j-1,blue_y,blue_x)){
move();
}
}
break;//가장 처음만나는 벽에서 멈춘다.
}else if(map[red_y][j].equals("O")){
result=Math.min(result,index+1);
break;
}
}
red_x=visit_x[index];
red_y=visit_y[index];
blue_x=visit_bx[index];
blue_y=visit_by[index];
stop=false;
/* blue left */
for(int j=blue_x-1;j>=0;j--){
if(map[blue_y][j].equals("#")){ //벽을 만났는데
if(red_y==blue_y && red_x<blue_x && j<red_x){
//B왼쪽에 R이있고 벽j가 R보다 왼쪽에있을때
blue_x=j+2;
}else{
blue_x=j+1;
}
break;
}else if(map[blue_y][j].equals("O")){
stop=true;
break;
}
}
/* red left */
for(int j=red_x-1;j>=0&&stop==false;j--){
if(map[red_y][j].equals("#")){ //벽을 만났는데
if(red_y==visit_by[index] && red_x>visit_bx[index] && j<visit_bx[index]){
if(promising(red_y,j+2,blue_y,blue_x)){
move();
}
}else{
if(promising(red_y,j+1,blue_y,blue_x)){
move();
}
}
break;//가장 처음만나는 벽에서 멈춘다.
}else if(map[red_y][j].equals("O")){
result=Math.min(result,index+1);
break;
}
}
}
check[visit_y[index]][visit_x[index]][visit_by[index]][visit_bx[index]]=0;
index--;
}
}
'코딩문제' 카테고리의 다른 글
[백준알고리즘] 주사위 굴리기 (0) | 2018.03.23 |
---|---|
[백준알고리즘] 2048 (BFS) (0) | 2018.03.23 |
[백준알고리즘] 숨바꼭질 (BFS) (0) | 2018.03.23 |
[백준알고리즘]1987 알파벳 (DFS) (0) | 2018.03.23 |
[백준알고리즘] 유기농 배추 (DFS) (0) | 2018.03.23 |