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 JAVA (judge verdict: Wrong Answer)

import java.util.*;
import java.lang.*;

/**
 * Rummy
 */
public class Main{

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.next());

        loop: for (int i = 0; i < n; i++) {
            int numList[] = new int[9];
            List<Integer> redList = new ArrayList<Integer>();
            List<Integer> greenList = new ArrayList<Integer>();
            List<Integer> blueList = new ArrayList<Integer>();

            for (int j = 0; j < 9; j++) {
                numList[j] = sc.nextInt();
            }
            for (int j = 0; j < 9; j++) {
                switch (sc.next()) {
                case "R":
                    redList.add(numList[j]);
                case "G":
                    greenList.add(numList[j]);
                case "B":
                    blueList.add(numList[j]);
                }
            }

            Collections.sort(redList);
            Collections.sort(greenList);
            Collections.sort(blueList);

            // まず3の倍数になってない時点でNg
            if (redList.size() % 3 != 0 || blueList.size() % 3 != 0 || greenList.size() % 3 != 0) {
                System.out.println(0);
                continue loop;
            }

            // 各色について全探索して, 連番or同じ数にできるか
            if (Confirm(redList) && Confirm(redList) && Confirm(redList)) {
                System.out.println(1);
            } else {
                System.out.println(0);
            }
        }
    }

    // bit全探索して, 連番or同じ数の組が作れたらtrueを返す
    private static boolean Confirm(List<Integer> list) {
        int len = list.size();

        // 長さ3の時
        if (len / 3 == 1) {
            if (list.get(0) == list.get(1) && list.get(1) == list.get(2)) {
                return true;
            } else if (list.get(0) + 1 == list.get(1) && list.get(1) + 1 == list.get(2)) {
                return true;
            } else {
                return false;
            }
        }

        // 長さ6の時
        if (len / 3 == 2) {
            for (int i = 0; i < 4; i++) {
                for (int j = i + 1; j < 5; j++) {
                    for (int k = j + 1; j < 6; k++) {
                        if (list.get(i) == list.get(j) && list.get(j) == list.get(k)) {
                            return true;
                        } else if (list.get(i) + 1 == list.get(j) && list.get(j) + 1 == list.get(k)) {
                            return true;
                        } else {
                            return false;
                        }
                    }
                }
            }
        }

        // // 長さ9の時
        // int[] bitList = new int[len]; // bitを入れる配列

        // for (int i = 0; i < pow(len / 3, len); i++) { // len=3 : 1, len=6 : 2^6,
        // len=9 : 3^9 かいまわる

        // for (int pos = 1; pos <= k; ++pos) {// 数字1~kが何文字分か仮定する
        // len[pos] = tmp % 3 + 1;// 1 ~ 3文字
        // tmp /= 3;
        // }
        // list[tmp] = true;
        // }

        // return true;
        return false;
    }
}