Problem:
Problem B: Red and Black

There is a rectangular room, covered with square tiles. Each tile is
colored either red or black. A man is standing on a black tile.
From a tile, he can move to one of four adjacent tiles. But he can't
move on red tiles, he can move only on black tiles.

Write a program to count the number of black tiles which he can reach
by repeating the moves described above.

Input

The input consists of multiple data sets.
A data set starts with a line containing two positive integers W and H;
W and H are the numbers of tiles in the x-
and y- directions, respectively. W and H are
not more than 20.

There are H more lines in the data set, each of which
includes W characters. Each character represents the color of a
tile as follows.

'.' - a black tile

'#' - a red tile

'@' - a man on a black tile(appears exactly once in a data set)

The end of the input is indicated by a line consisting of two zeros.

Output

For each data set, your program
should output a line which contains the number of
tiles he can reach from the initial tile (including itself).

Sample Input

6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0

Output for the Sample Input

45
59
6
13

Solution in C# (judge verdict: Accepted)

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

namespace V1130{
    public class Program{
        public static void Main(string[] args){
            var sr = new StreamReader();
            //---------------------------------
            while(true){
                var W = sr.Next<int>();
                var H = sr.Next<int>();
                var S = sr.Next<string>(H);
                if(W + H == 0) break;

                var visit = new bool[H, W].ToJaggedArray();
                var que = new Queue<int>();

                for(var i = 0; i < H; i++){
                    for(var j = 0; j < W; j++){
                        if(S[i][j] == '@'){
                            visit[i][j] = true;
                            que.Enqueue(j);
                            que.Enqueue(i);
                        }
                    }
                }

                var dx = new[]{0, 1, 0, -1};
                var dy = new[]{1, 0, -1, 0};
                Func<int, int, bool> isInside = (x, y) => 0 <= x && x < W && 0 <= y && y < H;

                while(que.Count > 0){
                    var x = que.Dequeue();
                    var y = que.Dequeue();
                    for(var i = 0; i < dx.Length; i++){
                        var nx = x + dx[i];
                        var ny = y + dy[i];
                        if(isInside(nx, ny) && S[ny][nx] == '.' && !visit[ny][nx]){
                            visit[ny][nx] = true;
                            que.Enqueue(nx);
                            que.Enqueue(ny);
                        }
                    }
                }

                Console.WriteLine(visit.SelectMany(a => a).Count(b => b));
            }
            //---------------------------------
        }
    }

    public static class ExMethod{
        public static T[][] ToJaggedArray<T>(this T[,] src){
            var x = src.GetLength(1);
            var y = src.GetLength(0);
            var ret = new T[y][];

            for(var i = 0; i < y; i++){
                ret[i] = new T[x];
                for(var j = 0; j < x; j++){
                    ret[i][j] = src[i, j];
                }
            }

            return ret;
        } 
    }

    public class StreamReader{
        private readonly char[] _c = {' '};
        private int _index = -1;
        private string[] _input = new string[0];
        private readonly System.IO.StreamReader _sr = new System.IO.StreamReader(Console.OpenStandardInput());

        public T Next<T>(){
            if(_index == _input.Length - 1){
                _index = -1;
                while(true){
                    string rl = _sr.ReadLine();
                    if(rl == null){
                        if(typeof(T).IsClass) return default(T);
                        return (T)typeof(T).GetField("MinValue").GetValue(null);
                    }
                    if(rl != ""){
                        _input = rl.Split(_c, StringSplitOptions.RemoveEmptyEntries);
                        break;
                    }
                }
            }
            return (T)Convert.ChangeType(_input[++_index], typeof(T), System.Globalization.CultureInfo.InvariantCulture);
        }

        public T[] Next<T>(int x){
            var ret = new T[x];
            for(var i = 0; i < x; ++i) ret[i] = Next<T>();
            return ret;
        }

        public T[][] Next<T>(int y, int x){
            var ret = new T[y][];
            for(var i = 0; i < y; ++i) ret[i] = Next<T>(x);
            return ret;
        }
    }
}