Problem:
Problem F: Line Puzzle

プログラミングでパズルを解いてみよう。

n × n の数字が格子状に並んでいる。数字のいくつかは丸で囲まれており、これらを起点と呼ぶことにする。パズルのルールは以下のとおりである：

各起点から縦・横に進む１本の線を引く（斜めには引けない）。

通った数字の和が起点の数字と同じになるように線を伸ばす。

線は枝分かれしてはいけない。

線はすでに引かれた数字を通ることはできない（線は交差してはいけない）。

線は２個以上の起点を通ることはできない。

下図に示すように、パズルのゴールはすべての起点を使い、すべての数字に線を引くことである。

あなたの仕事は、パズルを解くプログラムを作成することである。
ただしこの問題では、与えられたパズルが解けるものかどうかを判定するだけでよい。

Input

入力は複数のデータセットからなる。各データセットの形式は以下のとおりである：

n
n × n の数字

n × n の数字が与えられるパズルを示し、起点の数字は負の数として与えられる。

n が 0 のとき入力の終わりを示す。

n は 3 以上 8 以下、起点以外の数字は 1 以上 50 以下、起点は -50 以上 -1 以下であると仮定してよい。また、入力されるパズルの性質として以下のことを仮定してよい：

与えられるパズルの各行、各列には最低でも１つの起点がある。

起点の個数は、全体の数字の個数 (n × n) の 20 % から 40 % 程度である。

Output

各データセットに対して、パズルが解けるものであれば "YES" を、そうでなければ "NO" と１行に出力せよ。

Sample Input

3
-3 1 1
2 -4 1
2 1 -1
3
-4 1 1
1 1 -6
1 -5 3
4
-8 6 -2 1
2 -7 -2 1
1 -1 1 1
1 1 1 -5
6
2 2 3 -7 3 2
1 -10 1 1 3 2
2 6 5 2 -6 1
3 4 -23 2 2 5
3 3 -6 2 3 7
-7 2 3 2 -5 -13
6
2 2 3 -7 3 2
1 -10 1 1 3 2
2 6 5 2 -6 1
3 4 -23 2 2 5
3 3 -6 2 3 7
-7 2 3 2 -5 -12
0

Output for the Sample Input

YES
NO
NO
YES
NO

Solution in C# (judge verdict: Accepted)

using System;

public class Hello
{
    static int[] dx = new int[] { 0, 1, 0, -1 };
    static int[] dy = new int[] { 1, 0, -1, 0 };
    static bool OK = false;
    static int n = 0;
    public static void Main()
    {
        while (true)
        {
            n = int.Parse(Console.ReadLine().Trim());
            if (n == 0) break;
            OK = false;
            var map = new int[n, n];
            for (int i = 0; i < n; i++)
            {
                string[] line = Console.ReadLine().Trim().Split(' ');
                for (int j = 0; j < n; j++) map[i, j] = int.Parse(line[j]);
            }
            var used = new bool[n, n];
            goDfs(map, used, 0, n * n, 0, 0);
            Console.WriteLine(OK ? "YES" : "NO");
        }
    }
    public static void goDfs(int[,] map, bool[,] used, int rest, int rest2, int x, int y)
    {
        if (rest2 == 0) { OK = true; return; }
        if (rest == 0)
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    if (map[i, j] < 0 && !used[i, j])
                    {
                        used[i, j] = true;
                        goDfs(map, used, -map[i, j], rest2 - 1, i, j);
                        used[i, j] = false;
                        return;
                    }
        }
        else
            for (int i = 0; i < 4; i++)
            {
                var nx = x + dx[i];
                var ny = y + dy[i];
                if (nx >= 0 && nx < n && ny >= 0 && ny < n && map[nx, ny] > 0 && !used[nx, ny] && rest - map[nx, ny] >= 0)
                {
                    used[nx, ny] = true;
                    goDfs(map, used, rest - map[nx, ny], rest2 - 1, nx, ny);
                    used[nx, ny] = false;
                }
            }
    }
}