AOJ2153 Mirror Cave
問題リンク Mirror Cave
- 解法
(Linの位置, Renの位置)をノードにした幅優先探索で解けます。状態数は50^4なのでメモリもなんとか大丈夫です。
どちらか一方だけがゴールを踏んだ場合、それから先の状態を探索してはならないということに注意してBFSを書くだけです。
- ソース
import java.util.ArrayList; import java.util.List; import java.util.Scanner; //Mirror Cave public class AOJ2153 { void run(){ Scanner sc = new Scanner(System.in); int[][] m1 = {{-1,0},{0,1},{1,0},{0,-1}}, m2 = {{-1,0},{0,-1},{1,0},{0,1}}; for(;;){ int w = sc.nextInt(), h = sc.nextInt(); if((w|h)==0)break; sc.nextLine(); char[][] a = new char[h][], b = new char[h][]; for(int i=0;i<h;i++){ String[] s = sc.nextLine().split(" "); a[i] = s[0].toCharArray(); b[i] = s[1].toCharArray(); } int Li = 0, Lj = 0, Ri = 0, Rj = 0, GLi = 0, GLj = 0, GRi = 0, GRj = 0; for(int i=0;i<h;i++)for(int j=0;j<w;j++){ if(a[i][j]=='%'){ a[i][j] = '.'; GLi = i; GLj = j; } if(a[i][j]=='L'){ a[i][j] = '.'; Li = i; Lj = j; } if(b[i][j]=='%'){ b[i][j] = '.'; GRi = i; GRj = j; } if(b[i][j]=='R'){ b[i][j] = '.'; Ri = i; Rj = j; } } boolean[][][][] u = new boolean[h][w][h][w]; u[Li][Lj][Ri][Rj] = true; List<int[]> l = new ArrayList<int[]>(); l.add(new int[]{Li, Lj, Ri, Rj}); String res = "No"; while(!l.isEmpty()){ List<int[]> next = new ArrayList<int[]>(); for(int[] v:l){ int li = v[0], lj = v[1], ri = v[2], rj = v[3]; if(li==GLi&&lj==GLj||ri==GRi&&rj==GRj){ if(li==GLi&&lj==GLj&&ri==GRi&&rj==GRj){ res = "Yes"; next.clear(); break; } continue; } for(int k=0;k<4;k++){ int nli = li+m1[k][0], nlj = lj+m1[k][1], nri = ri+m2[k][0], nrj = rj+m2[k][1]; if(!(0<=nli&&nli<h&&0<=nlj&&nlj<w&&a[nli][nlj]=='.')){ nli = li; nlj = lj; } if(!(0<=nri&&nri<h&&0<=nrj&&nrj<w&&b[nri][nrj]=='.')){ nri = ri; nrj = rj; } if(!u[nli][nlj][nri][nrj]){ u[nli][nlj][nri][nrj] = true; next.add(new int[]{nli, nlj, nri, nrj}); } } } l = next; } System.out.println(res); } } public static void main(String[] args) { new AOJ2153().run(); } }