Problem:
城の堀

いま、忍者が城外から天守閣に忍び入ろうと計画を立てています。この忍者は地面を走ったり、堀の中を泳いだりすることは難なくできますが、堀から這い上がることはとても苦手なので、忍者は堀に入る回数をできるだけ少なくしたいと考えています。

お城の見取図を入力とし、城外から天守閣に至るまでに、堀から這い上がらなくてはならない最小回数を出力するプログラムを作成して下さい。お城の見取図は二次元格子として与えられます。見取り図に描かれた記号には、天守閣の位置を示す「&」と堀の位置を示す「#」の位置が記され、そのほかの地点には「.」（半角ピリオド）が記されています。なお、お城には天守閣は一つだけあるものとし、忍者は走ったり泳いだりして移動するときに東西南北方向に1マスずつ移動するものとし、斜めには移動しません。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロ２つの行で示されます。各データセットは以下の形式で与えられます。

n m
c1,1c1,2...c1,n
c2,1c2,2...c2,n
:
cm,1cm,2...cm,n

１行目に見取図の東西の幅 n と 南北の幅 m (1 ≤ n, m ≤ 100) が与えられる。続くm 行に見取り図の i 行目の情報が与えられる。各情報は記号「&」、「#」、「.」からなる長さ n の文字列である。

データセットの数は 50 を越えない。

Output

データセットごとに堀から這い上がらなくてはならない最小回数（整数）を１行に出力します。

Sample Input

5 5
.###.
#...#
#.&.#
#...#
.###.
18 15
..####....####....
####..####....####
#...............##
.#.############.##
#..#..........#.##
.#.#.########.#.##
#..#.#......#.#.##
.#.#....&...#.#.##
#..#........#.#.##
.#.#.########.#.##
#..#..........#.##
.#.############.##
#...............##
.#################
##################
9 10
#########
........#
#######.#
#.....#.#
#.###.#.#
#.#&#.#.#
#.#...#.#
#.#####.#
#.......#
#########
9 3
###...###
#.#.&.#.#
###...###
0 0

Output for the Sample Input

1
2
0
0

Solution in JAVA (judge verdict: Accepted)


import java.util.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Main {

	int INF = 1 << 28;
	int WALL = 10000;
	int GOAL = 100000;
	int w, h;
	int map[][];
	
	void run() {
		Scanner sc = new Scanner(System.in);
		for(;;) {
			w = sc.nextInt();
			h = sc.nextInt();
			if( (w|h) == 0 ) break;
			
			map = new int[h+2][w+2];
			for(int i=1;i<=h;i++) {
				String str = sc.next();
				for(int j=1;j<=w;j++) { 
					switch (str.charAt(j-1)) {
					case '#': map[i][j] = WALL; break;
					case '&': map[i][j] = GOAL; break;
					}
				}
			}

			int c=1;
			
			System.out.println(bfs());
		}
	}
	
	int dx[] ={-1,0,1,0};
	int dy[] ={0,-1,0,1};
	
	int bfs() {
		PriorityQueue<P> que = new PriorityQueue<P>();
		que.add(new P(0,0,0,false));
		map[0][0] = INF;
		
		for(;;) {
			P now = que.remove();
//			debug(now.x, now.y);
			for(int i=0;i<4;i++) {
				int nx = now.x + dx[i];
				int ny = now.y + dy[i];
				if( nx < 0 || nx >= w+2 || ny < 0 || ny >= h+2 ) continue;
				
				if( map[ny][nx] < WALL ) {
					map[ny][nx] = INF;
					que.add(new P(nx,ny,now.c,false));
				}
				else if(map[ny][nx] == WALL) {
					map[ny][nx] = INF;
					que.add(new P(nx,ny,now.c+(now.isWall? 0:1),true));
				}
				else if(map[ny][nx] == GOAL) return now.c;
			}
		}
	}
	
	class P implements Comparable<P>{
		int x, y, c;
		boolean isWall;
		P(int x, int y, int c, boolean w) {
			this.x = x;
			this.y = y;
			this.c = c;
			isWall = w;
		}
		@Override
		public int compareTo(P o) {
			// TODO 自動生成されたメソッド・スタブ
			if(c != o.c)
				return c-o.c;
			return isWall? -1:1;
		}
	}

	public static void main(String[] args) {
		new Main().run();
	}

	void debug(Object... os) {
		System.err.println(Arrays.deepToString(os));
	}
}