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: Time Limit Exceeded)

import java.util.Scanner;

public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		int[] n = new int[9];
		int[] red = new int[9];
		int[] blue = new int[9];
		int[] green = new int[9];
		int r, g, b;
		int[][] R = new int[10][10];
		int[][] G = new int[10][10];
		int[][] B = new int[10][10];
		int[] numR = new int[10];
		int[] numG = new int[10];
		int[] numB = new int[10];
		char c;
		int count;
		int t = sc.nextInt();
		for(int k = 0; k < t; k++){
			r = 0;
			g = 0;
			b = 0;
			for(int i = 1; i <= 9; i++){
				numR[i] = 0;
				numG[i] = 0;
				numB[i] = 0;
			}
			count = 0;
			for(int i = 0; i < 9; i++)
				n[i] = sc.nextInt();
			for(int i = 0; i < 9; i++){
				c = sc.next().charAt(0);
				switch(c){
				case 'R':
					red[r] = n[i];
					r++;
					break;
				case 'G':
					green[g] = n[i];
					g++;
					break;
				case 'B':
					blue[b] = n[i];
					b++;
					break;
				default:
					System.out.println("Error");
					i = -1;
					break;
				}
			}
			sort(R, numR, red, r);
			sort(G, numG, green, g);
			sort(B, numB, blue, b);
			count += set(R, numR) + set(G, numG) + set(B, numB);			
			System.out.println(count == 3 ? 1 : 0);
		}
	}
	static void sort(int[][] C, int[] numC, int[] color, int c){
		for(int i = 0; i < c; i++){
			for(int j = 1; j <= 9; j++)
				if(color[i] == j){
					C[j][++numC[j]] = 1;
			}
		}
	}
	static int set(int[][] C, int[] numC){
		int count = 0;
		for(int i = 1; i <= 9; i++){
			for(int k = 0; k < 3; k++){
				if(numC[i] >= 3){
					numC[i] -= 3;
					count++;
				}else
					break;
			}
			for(int j = numC[i]+1; j <= 9; j++)
				C[i][j] = 0;
		}
		for(int i = 1; i <= 7; i++){
			if(C[i][1] == 1 && C[i+1][1] == 1 && C[i+2][1] == 1){
				count++;
				C[i][1] = C[i][2];
				C[i+1][1] = C[i+1][2];
				C[i+2][1] = C[i+2][2];
				i = 0;
			}
		}
		return count;
	}
}