Problem:
Problem B: Independent Research

Problem

僕は夏休みの自由研究のテーマとして、生き物観察を選択し、生き物観察キットを購入した。

この生き物は3次元グリッド状の空間を好んで生息する。
各セルには最大1匹までしか入れない。
周囲の環境に合わせ1日が経過するごとに誕生と死滅を繰り返す。

誕生と死滅の条件は、セルに隣接する生き物の数に依存する。
ここで、あるセルに生き物が隣接するとは、あるセルと生き物が生息しているもう一つのセルが面、辺、または点を共有していることを言う。
誕生と死滅のルールは次のようになる。

生き物が生息していないセルにおいて、隣接する生き物の数が
ai (1 ≤ i ≤ M1 ) 匹であるような
i がある場合、そのセルに生き物が誕生する。

生き物が生息しているセルにおいて、隣接する生き物の数が
bj (1 ≤ j ≤ M2 ) 匹であるような
j がない場合、そのセルの生き物は死滅する。

今回購入した飼育箱はセルの数が5*5*5である立方体の飼育箱だ。
この飼育箱ではこの生き物はどのような振る舞いをするのだろうか…？　とても楽しみである。

〜数日後〜

とりあえず、飼育してみたが…　

毎日観察するなんて時間がかかるし、僕にはめんどくさくてやる気がおきない。

そうだ、コンピューターとプログラムを使ってシミュレートしよう。

Input

入力は複数のデータセットからなる。
各データセットは以下のフォーマットで与えられる。

N
(z = 0 の飼育箱の状態)
(空行)
(z = 1 の飼育箱の状態)
(空行)
(z = 2 の飼育箱の状態)
(空行)
(z = 3 の飼育箱の状態)
(空行)
(z = 4 の飼育箱の状態)
(空行)
M1 a1 a2 …　aM1
M2 b1 b2 …　bM2

最初にシミュレートする日数 N が与えられる。

次に飼育箱の初期状態の情報が与えられる。これは5つの5*5の2次元グリッドで与えられる。

各2次元グリッドは0と1から成り立ち、1は生き物がいることを示し、0は何もいないことを示す。

例えば、 z = 0のセルの状態の2次元グリッドの4行2列目の値が1だった場合、飼育箱の座標(1, 3, 0)の位置に生き物がいることを表す。

次に、整数 M1 が与えられ、そのあとに M1 個の数字 ai が与えられる。

次に、整数 M2 が与えられ、そのあとに M2 個の数字 bj が与えられる。

入力の終わりは N = 0で表される。

Constraints

入力は以下の条件を満たす。

1 ≤ N ≤ 100

0 ≤ M1 , M2 ≤ 27

0 ≤ ai , bj ≤ 26
(1 ≤ i ≤ M1 , 1 ≤ j ≤ M2 )

任意の i , j (1 ≤ i < j ≤ M1 )
において、 ai ≠ aj

任意の i , j (1 ≤ i < j ≤ M2 )
において、 bi ≠ bj

Output

各データセットに対し、 N 日経過後の状態を出力せよ。

出力は以下のフォーマットに従う。

Case (テストケースの番号):
(z = 0 の飼育箱の状態)
(空行)
(z = 1 の飼育箱の状態)
(空行)
(z = 2 の飼育箱の状態)
(空行)
(z = 3 の飼育箱の状態)
(空行)
(z = 4 の飼育箱の状態)

1行目にテストケース番号を出力し、次の行から N 日経過後の状態として、5*5の2次元グリッドを5つ出力せよ。

各テストケースの出力間には空行を出力しなさい。

Sample Input

5
00000
01010
00000
00100
00000

00000
01010
00000
01010
00000

00000
00100
00000
01010
00000

00000
01010
00000
00100
00000

00000
00000
00100
00000
00000

1 2
2 3 4
4
01110
00100
00100
00100
01110

01110
10001
10000
10001
01110

11111
10001
11111
10000
10000

01110
10001
10000
10001
01110

00000
00000
00000
00000
00000

2 3 4
1 2
100
00100
01010
01110
10001
10001

01110
00100
00100
00100
01110

00000
00000
00000
00000
00000

11111
00010
00100
01000
11111

10001
10001
10001
10001
01110

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

Sample Output

Case 1:
00000
00000
01010
01110
10101

00000
10001
00000
00000
00000

00000
00000
11111
10001
00000

00000
00000
00000
00000
01010

00000
00000
01110
00100
11111

Case 2:
00010
10110
00000
11000
10000

00001
00000
10101
00010
00100

10001
00000
00000
00000
00010

01110
10001
00000
00001
10000

00000
00000
00111
01001
01000

Case 3:
00000
00000
00000
00000
00000

00000
00000
00000
00000
00000

00000
00000
00000
00000
00000

00000
00000
00000
00000
00000

00000
00000
00000
00000
00000

Solution in JAVA (judge verdict: Accepted)

import static java.lang.System.*;
import java.util.*;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner sc = new Scanner(in);
		
		for(int seti=1; ; seti++) {
			int n = sc.nextInt();
			if(n==0) break;
			
			boolean[][][] map = new boolean[5][5][5];
			for(int i=0; i<5; i++) {
				for(int j=0; j<5; j++) {
					char[] tmp = sc.next().toCharArray();
					for(int k=0; k<5; k++) {
						map[i][j][k] = tmp[k] == '1';
					}
				}
			}

			ArrayList<Integer> birth = new ArrayList<Integer>();
			ArrayList<Integer> die = new ArrayList<Integer>();

			int b = sc.nextInt();
			for(int i=0; i<b; i++) birth.add(sc.nextInt());
			int d = sc.nextInt();
			for(int i=0; i<d; i++) die.add(sc.nextInt());

			while(n-->0) {
				boolean[][][] next = new boolean[5][5][5];
				
				for(int i=0; i<5; i++) {
					for(int j=0; j<5; j++) {
						for(int k=0; k<5; k++) {
							int count = 0;
							for(int x=-1; x<=1; x++) {
								for(int y=-1; y<=1; y++) {
									for(int z=-1; z<=1; z++) {
										if(x==0 && y==0 && z==0) continue;
										
										int nz = i + z;
										int ny = j + y;
										int nx = k + x;
										
										if(!(0<=nx && nx<5 && 0<=ny && ny<5 && 0<=nz && nz<5)) continue;
										if(map[nz][ny][nx]) count++;
										
//										out.println(" " + nz + " " + ny + " " + nx + "  " + (map[nz][ny][nx] ? "T":"F"));
									}
								}
							}
//							out.println(i + " " + j + " " + k + " " + count);
							
							next[i][j][k] = false;
							if(!map[i][j][k]) {
								for(int c: birth) {
									if(count == c) {
										next[i][j][k] = true;
										break;
									}
								}
							}
							else {
								for(int c: die) {
									if(count == c) {
										next[i][j][k] = true;
										break;
									}
								}
							}
						}
					}
				}
				
				map = next;
			}
			
			if(seti != 1) out.println();
			out.println("Case " + seti + ":");

			for(int i=0; i<5; i++) {
				for(int j=0; j<5; j++) {
					for(int k=0; k<5; k++) {
						out.print(map[i][j][k] ? "1": "0");
					}
					out.println();
				}
				if(i!=4) out.println();
			}
		}
	}

}