예전에 알고리즘 수업시간에 테세우스 게임 알고리즘과 비슷하게 풀었음! (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--; } }


+ Recent posts