Problem:
パズル

1 〜 9 の数字を 14 個組み合わせて完成させるパズルがあります。与えられた 13 個の数字にもうひとつ数字を付け加えて完成させます。

パズルの完成条件は

同じ数字を２つ組み合わせたものが必ずひとつ必要です。

残りの12 個の数字は、３個の数字の組み合わせ４つです。

３個の数字の組み合わせ方は、同じ数字を３つ組み合わせたものか、または３つの連続する数字を組み合わせたものです。ただし、9 1 2 のような並びは連続する数字とは認められません。

同じ数字は4 回まで使えます。

13 個の数字からなる文字列を読み込んで、パズルを完成することができる数字を昇順に全て出力するプログラムを作成してください。なお、1〜9 のどの数字を付け加えてもパズルを完成させることができないときは 0 を出力してください。

例えば与えられた文字列が 3456666777999 の場合

「2」があれば、　234 567 666 77 999

「3」があれば、　33 456 666 777 999

「5」があれば、　345 567 666 77 999

「8」があれば、　345 666 678 77 999

というふうに、2 3 5 8 のいずれかの数字が付け加えられるとパズルは完成します。「6」でも整いますが、5 回目の使用になるので、この例では使えないことに注意してください。

Input

入力は複数のデータセットからなります。各データセットとして、13 個の数字が１行に与えられます。データセットの数は 50 を超えません。

Output

データセットごとに、パズルを完成させることができる数字を昇順に空白区切りで１行に出力します。

Sample Input

3649596966777
6358665788577
9118992346175
9643871425498
7755542764533
1133557799246

Output for the Sample Input

2 3 5 8
3 4
1 2 3 4 5 6 7 8 9
7 8 9
1 2 3 4 6 7 8
0

Solution in C# (judge verdict: Accepted)

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

namespace AOJ
{
    class Program
    {
        static bool CheckRec(int[] data)
        {
            if (data.Sum() == 0) return true;

            for (int j = 0; j < 7; j++)
            {
                if (data[j] <= 0 || data[j + 1] <= 0 || data[j + 2] <= 0) continue;
                data[j]--;
                data[j + 1]--;
                data[j + 2]--;
                if (CheckRec(data)) return true;
                data[j]++;
                data[j + 1]++;
                data[j + 2]++;
            }

            for (int j = 0; j < 9; j++)
            {
                if (data[j] < 3) continue;
                data[j] -= 3;
                if (CheckRec(data)) return true;
                data[j] += 3;
            }

            return false;
        }

        static bool Check2(int[] data, int[] buf)
        {
            for(int j = 0; j < 9; j++)
            {
                Array.Copy(data, buf, data.Length);
                if (buf[j] < 2) continue;
                if (buf.Max() > 4) continue;
                buf[j] -= 2;
                if (CheckRec(buf)) return true;
            }
            return false;
        }
        static IEnumerable<int> Check(int[] data)
        {
            for (int i = 0; i < 9; i++)
            {
                data[i]++;
                if (Check2(data, new int[data.Length]))
                    yield return i;
                data[i]--;
            }
        }
        static void Main(string[] args)
        {
            string line;
            var data = new int[9];
            while((line = Console.ReadLine()) != null)
            {
                Array.Clear(data, 0, data.Length);
                foreach(var c in line)
                {
                    data[c - '1']++;
                }
                var a = string.Join(" ", Check(data).Select(x => ((char)(x + '1')).ToString()).ToArray());
                Console.WriteLine(string.IsNullOrEmpty(a) ? "0" : a);
            }
        }
    }
}