Problem:
Problem C: ラミー

あなたの友達は最近 UT-Rummy というカードゲームを思いついた．

このゲームで使うカードには赤・緑・青のいずれかの色と1から9までのいずれかの番号が
つけられている．
このゲームのプレイヤーはそれぞれ9枚の手札を持ち，
自分のターンに手札から1枚選んで捨てて，
代わりに山札から1枚引いてくるということを繰り返す．
このように順番にターンを進めていき，
最初に手持ちのカードに3枚ずつ3つの「セット」を作ったプレイヤーが勝ちとなる．
セットとは，同じ色の3枚のカードからなる組で，すべて同じ数を持っているか
連番をなしているもののことを言う．
連番に関しては，番号の巡回は認められない．
例えば，7, 8, 9は連番であるが 9, 1, 2は連番ではない．

あなたの友達はこのゲームをコンピュータゲームとして売り出すという計画を立てて，
その一環としてあなたに勝利条件の判定部分を作成して欲しいと頼んできた．
あなたの仕事は，手札が勝利条件を満たしているかどうかを判定する
プログラムを書くことである．

Input

入力の1行目にはデータセット数を表す数 T
(0 < T ≤ 50) が与えられる．
この行に引き続き T 個のデータセットが与えられる．

各データセットは2行からなり，
1行目には i 番目
(i = 1, 2, ..., 9)
のカードの数字 ni
がそれぞれスペースで区切られて与えられ，
2行目には i 番目のカードの色を表す文字
ci
がそれぞれスペースで区切られて与えられる．
カードの数字
ni
は 1 ≤ ni ≤ 9
を満たす整数であり，
カードの色 ci
はそれぞれ “R”, “G”,
“B”
のいずれかの文字である．

1つのデータセット内に色と数字がともに同じカードが5枚以上出現することはない．

Output

各データセットにつき，勝利条件を満たしていれば
“1”，
そうでなければ “0” と出力せよ．

Sample Input

5
1 2 3 3 4 5 7 7 7
R R R R R R G G G
1 2 2 3 4 4 4 4 5
R R R R R R R R R
1 2 3 4 4 4 5 5 5
R R B R R R R R R
1 1 1 3 4 5 6 6 6
R R B G G G R R R
2 2 2 3 3 3 1 1 1
R G B R G B R G B

Output for the Sample Input

1
0
0
0
1

Solution in C# (judge verdict: Accepted)

/* Rummy (???????????????????????§??????????????´???) */

using System;

namespace rummy_card
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = ReadNumber();

            for (int i = 0; i < n; i++)
            {
                Hand rummyHand = new Hand();

                Console.WriteLine(rummyHand.IsWinner() ? "1" : "0");

            }

        }


        /// <summary>
        /// ?¨?????????????????????????????????´??°??????????????¨???????????????????????????
        /// AOJ????????§??????????????????
        /// </summary>
        /// <returns>??????????????????????????°????????????????????£?????´??°???</returns>
        private static int ReadNumber()
        {
            int n = 0;
            if (!int.TryParse(Console.ReadLine(), out n))
            {
                /*???????????±??????????????\????????? ?????????????????´???????????????0?????????*/
                Console.WriteLine("error:ReadNumber");
            }
            return n;
        }
    }
}

/// <summary>
/// ??????????????????
/// </summary>
public class Card
{
    /// <summary>
    /// ???????????????
    /// </summary>
    public string _color = null;

    /// <summary>
    /// ??????????????°???
    /// </summary>
    public int _number = 0;

    /// <summary>
    /// ????????????ID
    /// ??°??????????????????????????????4??????????????§??????????????§1???4???????????????????????¨??????
    /// </summary>
    public int _id = 0;


    /// <summary>
    /// ?????????????????????
    /// Hand???????????????????????????????????°??????
    /// ????????´???_id???Hand???????????????
    /// </summary>
    public Card(string color, string number)
    {
        _color = color;
        _number = int.Parse(number);
    }


}

/// <summary>
/// ???????????????
/// 9??????????????????????????¨???????????? ?????????????????§??????
/// </summary>
public class Hand
{
    Card[] _cards = new Card[9];

    /// <summary>
    /// ?????????????????????
    /// ?????°?????????AOJ????????¨?????????
    /// </summary>
    public Hand()
    {
        string[] number = Console.ReadLine().Split(' ');
        string[] color = Console.ReadLine().Split(' ');

        for (int i = 0; i < 9; i++)
        {
            _cards[i] = new Card(color[i], number[i]);
            int ID = 1;                                 //???????????????_id

            for (int j = 0; j < i; j++)
            {
                if (_cards[j]._color == _cards[i]._color &&
                    _cards[j]._number == _cards[i]._number)
                {
                    ID++;       //?????¨??°???????????´???????????????????????????????????????????????????ID?????????????????????????????????
                }
            }
            _cards[i]._id = ID;
        }
        Sort();                 //??????????????±????????????????????£?????????????????????????????????
    }

    /// <summary>
    /// ???????????¶????????¨??????????????????????????°??¨???
    /// </summary>
    internal void Display()
    {
        for (int i = 0; i < 9; i++)
        {
            Console.Write(_cards[i]._color + _cards[i]._number + "({0}) ", _cards[i]._id);
        }
        Console.WriteLine();
    }

    internal bool IsWinner()
    {
        /*?????£????????????true ?????£?????????????????????false*/
        bool[] flag = new bool[9];

        for (int i = 0; i < 9; i++)
        {


            if (!flag[i])   //??°??????????????????????????????????????§??????????????????????????????????????????????????????????????¨???????????????
            {
                MeldGroup(flag, i);
            }

            if (!flag[i])   //???????????£????????§????????????????????????
            {
                MeldRun(flag, i);
            }

            if (!flag[i])
            {

                return false;       //??????????????±??????????????????????????????????????£??????????????§?????????                            
            }
        }
        /*false???????????????for???????????????????????´?????¨??????flag???true*/

        return true;
    }

    /// <summary>
    /// ????????°?????¶????????¨??? ???????????°??¨
    /// </summary>
    /// <param name="flag"></param>
    private void ShowFlag(bool[] flag)
    {
        foreach (bool x in flag)
        {
            Console.Write(x ? "1 " : "0 ");
        }
        Console.WriteLine();
    }

    /// <summary>
    /// ????????§???????????§??????????????????
    /// </summary>
    /// <param name="flag">???????????????????????£???????????£???????????????</param>
    /// <param name="i">???????????°</param>
    private void MeldRun(bool[] flag, int i)
    {
        for (int j = i + 1; j < 9; j++)    //???????????£?????????????????????????????§??°??????1??§????????????????????????????????????
        {
            if (_cards[i]._color == _cards[j]._color &&
               _cards[i]._number + 1 == _cards[j]._number &&
                    !flag[j])
            {
                for (int k = j + 1; k < 9; k++)     //1??§?????????????????????????????£?????????????§????2??§????????????????????????????????????
                {
                    if (_cards[i]._color == _cards[k]._color &&
                       _cards[i]._number + 2 == _cards[k]._number &&
                            !flag[k])
                    {
                        flag[i] = true;
                        flag[j] = true;
                        flag[k] = true;
                        return;
                    }
                }
            }
        }
    }

    /// <summary>
    /// ??°???????????§???????????§??????????????????
    /// </summary>
    /// <param name="flag">???????????????????????£???????????£???????????????</param>
    /// <param name="i">???????????°</param>
    private void MeldGroup(bool[] flag, int i)
    {
        if (_cards[i]._id >= 3)
        {
            flag[i] = true;
            flag[i + 1] = true;
            flag[i + 2] = true;
        }
    }

    /// <summary>
    /// ???????????´????????????????????????
    /// </summary>
    internal void Sort()
    {
        Array.Sort(_cards, (a, b) => Compare(a, b));
    }

    /// <summary>
    /// 2?????????????????? ??? > ??°??? > ID ?????????????????§????????????
    /// </summary>
    /// <param name="a">??????????±?</param>
    /// <param name="b">??????????±?</param>
    /// <returns></returns>
    private int Compare(Card a, Card b)
    {
        int iCompare = b._color.CompareTo(a._color);    //R???G???B????????§?????????????????????????????????
        if (iCompare != 0)
        {
            return iCompare;
        }
        else                        //?????????????????°??????????????§????????????
        {
            if (a._number - b._number != 0)
            {
                return a._number - b._number;
            }
            else                    //??°??????????????????id???????????§????????????
            {
                return b._id - a._id;
            }
        }

    }
}