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 C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    struct State
    {
        internal int x, y, cnt;

        public State(int x, int y, int cnt)
        {
            this.x = x;
            this.y = y;
            this.cnt = cnt;
        }
    }

    class Problem
    {
        readonly int[] moveX = new int[] { -1, 0, 1, 0 };
        readonly int[] moveY = new int[] { 0, -1, 0, 1 };
        readonly int INF = 1 << 20;
        readonly int w, h;

        int[,] map, memo;
        int sx, sy;

        public Problem(int w, int h)
        {
            this.w = w;
            this.h = h;
            map = new int[h, w];
            memo = new int[h, w];
            MakeMap();
        }

        public int Solve()
        {
            int ret = INF;

            Stack<State> stk = new Stack<State>();
            stk.Push(new State(sx, sy, 0));

            while (stk.Count > 0)
            {
                State cur = stk.Pop();
                memo[cur.y, cur.x] = cur.cnt;

                for (int i = 0; i < 4; i++)
                {
                    int nx = cur.x + moveX[i];
                    int ny = cur.y + moveY[i];

                    if (IsValid(nx, ny))
                    {
                        int tempCnt = cur.cnt + (map[cur.y, cur.x] == 1 ? 0 : map[ny, nx]);

                        if (tempCnt < memo[ny, nx] && tempCnt < ret)
                        {
                            stk.Push(new State(nx, ny, tempCnt));
                        }
                    }
                    else ret = Math.Min(ret, cur.cnt);
                }
            }
            return ret;
        }

        private bool IsValid(int x, int y)
        {
            if (x >= 0 && x < w && y >= 0 && y < h) return true;
            return false;
        }

        private void MakeMap()
        {
            for (int i = 0; i < h; i++)
            {
                string input = Console.ReadLine();

                for (int j = 0; j < w; j++)
                {
                    switch (input[j])
                    {
                        case '#':
                            map[i, j] = 1;
                            break;
                        case '&':
                            sx = j;
                            sy = i;
                            break;
                    }
                    memo[i, j] = INF;
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder();

            while (true)
            {
                string[] input = Console.ReadLine().Split(' ');
                int w = int.Parse(input[0]);
                int h = int.Parse(input[1]);

                if (w == 0 && h == 0) break;

                Problem pb = new Problem(w, h);
                sb.AppendLine(pb.Solve().ToString());
            }
            Console.Write(sb);
        }
    }
}