Problem:
Problem D: Smartphone Game
Problem
人気のスマフォゲームの一機能を実装してみよう。ゲームは以下の仕様に基づく。
5*5のマスに、5種類のブロックが設置されている。
それぞれの種類のブロックには得点が設定されている。
得点には、ブロックの得点の他に、ボーナス得点が設定されている。最初のボーナス得点は1である。
ブロックを任意に1つだけ決めて、最大で
n
回まで上下左右に移動できる。移動先のブロックは移動元のブロックのあった場所に移動する。つまり、隣接したブロックを交換する事になる。
移動した後、同じ種類のブロックが縦3個以上又は横3個以上に並んだ場合、並んだブロックは全て消える。
消えるべきブロックが全て消えた後、あるブロックの下に別のブロックが存在しない場合、そのブロックは落下する。落下とは、あるブロックの１つ上に辿り着くまで下に移動する事をいう。ブロックが下に存在しない場合は一番下に移動する。
全てのブロックの落下後にボーナス得点が1だけ加算される。
その後にブロックが並んだ場合、さらに消え、落下する。
ブロックが消える時に、ブロック１つにつき「ブロックの得点*ボーナス得点」が自分の得点に加算される。
１回のプレイで得られる最大の点数を求めよ。
Input
入力は複数のデータセットからなる。
各データセットは以下で表される。
n
a
11
..
a
15
.
.
a
51
..
a
55
score
1
..
score
5
a
ij
は1から5までの数字で、ブロックの種類を表す。
score
i
は
i
種類目のブロック１つ分の得点を表す。
n
= -1 の時、入力が終了する。
Constraints
入力は以下の条件を満たす。
0 ≤
n
≤ 5
1 ≤
a
ij
≤ 5
0 ≤
score
i
≤ 100
テストケースの数は 10 を超えない。
入力に含まれる値は全て整数である。
Output
各データセット毎に、答えを一行に出力しなさい。
Sample Input
0
1 1 1 5 5
5 5 5 5 5
5 5 1 5 5
5 1 1 1 5
5 5 5 5 5
0 0 0 0 1
2
1 2 3 4 5
2 3 4 5 5
2 3 4 5 5
3 4 5 5 1
5 4 3 2 1
100 99 98 97 96
5
1 2 3 4 5
2 3 4 5 1
1 2 3 4 5
5 4 3 2 1
1 2 3 4 5
99 79 31 23 56
-1
Sample Output
17
2040
926

Submitted solutions:

code_snippet: // AOJ #1512 Smartphone Game
// 2025.2.20

#include <bits/stdc++.h>
using namespace std;

const int NROWS = 5, NCOLS = 5;
int dr[4] = {-1,1,0,0};
int dc[4] = {0,0,-1,1};

vector<int> blockScore(6);

int simulateChain(vector<vector<int>> board) {
    int totalScore = 0;
    int bonus = 1;
    
    while (true) {
        vector<vector<bool>> mark(NROWS, vector<bool>(NCOLS, false));
        bool anyMark = false;
        
        for (int r = 0; r < NROWS; r++) {
            int c = 0;
            while (c < NCOLS) {
                if(board[r][c] == 0) { c++; continue; }
                int start = c;
                int curType = board[r][c];
                while(c < NCOLS && board[r][c] == curType) c++;
                int len = c - start;
                if(len >= 3) {
                    for (int j = start; j < c; j++) {
                        mark[r][j] = true;
                        anyMark = true;
                    }
                }
            }
        }
        
        for (int c = 0; c < NCOLS; c++) {
            int r = 0;
            while (r < NROWS) {
                if(board[r][c] == 0) { r++; continue; }
                int start = r;
                int curType = board[r][c];
                while(r < NROWS && board[r][c] == curType) r++;
                int len = r - start;
                if(len >= 3) {
                    for (int i = start; i < r; i++) {
                        mark[i][c] = true;
                        anyMark = true;
                    }
                }
            }
        }
        
        if(!anyMark) break;
        
        for (int r = 0; r < NROWS; r++) {
            for (int c = 0; c < NCOLS; c++) {
                if(mark[r][c]) {
                    int type = board[r][c];
                    totalScore += blockScore[type] * bonus;
                    board[r][c] = 0;
                }
            }
        }
        
        for (int c = 0; c < NCOLS; c++) {
            int write = NROWS - 1;
            for (int r = NROWS - 1; r >= 0; r--) {
                if(board[r][c] != 0) {
                    board[write][c] = board[r][c];
                    write--;
                }
            }
            for (int r = write; r >= 0; r--) board[r][c] = 0;
        }
        bonus++;
    }
    return totalScore;
}

int dfs(vector<vector<int>> board, int r, int c, int moves, int maxMoves) {
    int best = simulateChain(board);
    if(moves == maxMoves) return best;

    for(int d=0; d<4; d++){
        int nr = r + dr[d], nc = c + dc[d];
        if(nr < 0 || nr >= NROWS || nc < 0 || nc >= NCOLS) continue;
        vector<vector<int>> nextBoard = board;
        swap(nextBoard[r][c], nextBoard[nr][nc]);
        int candidate = dfs(nextBoard, nr, nc, moves+1, maxMoves);
        best = max(best, candidate);
    }
    return best;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    while(true){
        int n;
        cin >> n;
        if(n == -1) break;
        
        vector<vector<int>> board(NROWS, vector<int>(NCOLS));
        for(int i=0; i<NROWS; i++){
            for(int j=0; j<NCOLS; j++) cin >> board[i][j];
        }
        
        for(int i=1; i<=5; i++) cin >> blockScore[i];
        
        int answer = 0;
        for (int r = 0; r < NROWS; r++) {
            for (int c = 0; c < NCOLS; c++)
                answer = max(answer, dfs(board, r, c, 0, n));
        }
        cout << answer << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3468
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <cassert>
using namespace std;

int Score[6];
int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };

// 再実装
struct State {
	int v[7][7];
};

// スコア計算
int CalculateScore(State S) {
	int CurrentScore = 0;
	int BonusScore = 0;

	// シミュレーション
	while (true) {
		BonusScore += 1;
		vector<vector<bool>> Delete(5, vector<bool>(5, false));
		for (int i = 0; i < 5; i++) {
			if (S.v[i][0] == S.v[i][1] && S.v[i][1] == S.v[i][2] && S.v[i][0] != 0) { Delete[i][0] = true; Delete[i][1] = true; Delete[i][2] = true; }
			if (S.v[i][1] == S.v[i][2] && S.v[i][2] == S.v[i][3] && S.v[i][1] != 0) { Delete[i][1] = true; Delete[i][2] = true; Delete[i][3] = true; }
			if (S.v[i][2] == S.v[i][3] && S.v[i][3] == S.v[i][4] && S.v[i][2] != 0) { Delete[i][2] = true; Delete[i][3] = true; Delete[i][4] = true; }
		}
		for (int i = 0; i < 5; i++) {
			if (S.v[0][i] == S.v[1][i] && S.v[1][i] == S.v[2][i] && S.v[0][i] != 0) { Delete[0][i] = true; Delete[1][i] = true; Delete[2][i] = true; }
			if (S.v[1][i] == S.v[2][i] && S.v[2][i] == S.v[3][i] && S.v[1][i] != 0) { Delete[1][i] = true; Delete[2][i] = true; Delete[3][i] = true; }
			if (S.v[2][i] == S.v[3][i] && S.v[3][i] == S.v[4][i] && S.v[2][i] != 0) { Delete[2][i] = true; Delete[3][i] = true; Delete[4][i] = true; }
		}

		// 消す処理
		int NewScore = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (Delete[i][j] == true) { NewScore += Score[S.v[i][j]]; S.v[i][j] = 0; }
			}
		}
		CurrentScore += NewScore * BonusScore;
		if (NewScore == 0) break;

		// 落ちる処理
		for (int k = 0; k < 5; k++) {
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 5; j++) {
					if (S.v[i + 1][j] == 0 && S.v[i][j] != 0) swap(S.v[i + 1][j], S.v[i][j]);
				}
			}
		}
	}

	// 答えを返す
	return CurrentScore;
}

// 全探索
int Solve(int dep, int px, int py, State S) {
	if (dep == 0) return CalculateScore(S);

	// 再帰呼び出し
	int Max = CalculateScore(S);
	for (int i = 0; i < 4; i++) {
		int ex = px + dx[i];
		int ey = py + dy[i];
		if (ex < 0 || ey < 0 || ex > 4 || ey > 4) continue;
		State T = S; swap(T.v[px][py], T.v[ex][ey]);
		int ret = Solve(dep - 1, ex, ey, T);
		Max = max(Max, ret);
	}

	// 答えを返す
	return Max;
}

int main() {
	while (true) {
		// Step 1. Input
		int N; cin >> N; if (N == -1) break;
		State S;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) cin >> S.v[i][j];
		}
		for (int i = 1; i <= 5; i++) cin >> Score[i];

		// 制約違反をチェック
		assert(0 <= N && N <= 5);
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) assert(1 <= S.v[i][j] && S.v[i][j] <= 5);
		}
		for (int i = 1; i <= 5; i++) {
			assert(0 <= Score[i] && Score[i] <= 100);
		}
		
		// Step 2. Brute Force
		int Answer = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				Answer = max(Answer, Solve(N, i, j, S));
			}
		}

		// Step 3. Output
		cout << Answer << endl;
	}
	return 0;
}
accuracy: 0.7142857142857143
time_ms: 50
memory_kb: 3336
final_rank: 16

code_snippet: #include <iostream>
#include <vector>
using namespace std;

int Score[6];
int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };

// 再実装
struct State {
	int v[7][7];
};

// スコア計算
int CalculateScore(State S) {
	int CurrentScore = 0;
	int BonusScore = 0;

	// シミュレーション
	while (true) {
		BonusScore += 1;
		vector<vector<bool>> Delete(5, vector<bool>(5, false));
		for (int i = 0; i < 5; i++) {
			if (S.v[i][0] == S.v[i][1] && S.v[i][1] == S.v[i][2] && S.v[i][0] != 0) { Delete[i][0] = true; Delete[i][1] = true; Delete[i][2] = true; }
			if (S.v[i][1] == S.v[i][2] && S.v[i][2] == S.v[i][3] && S.v[i][1] != 0) { Delete[i][1] = true; Delete[i][2] = true; Delete[i][3] = true; }
			if (S.v[i][2] == S.v[i][3] && S.v[i][3] == S.v[i][4] && S.v[i][2] != 0) { Delete[i][2] = true; Delete[i][3] = true; Delete[i][4] = true; }
		}
		for (int i = 0; i < 5; i++) {
			if (S.v[0][i] == S.v[1][i] && S.v[1][i] == S.v[2][i] && S.v[0][i] != 0) { Delete[0][i] = true; Delete[1][i] = true; Delete[2][i] = true; }
			if (S.v[1][i] == S.v[2][i] && S.v[2][i] == S.v[3][i] && S.v[1][i] != 0) { Delete[1][i] = true; Delete[2][i] = true; Delete[3][i] = true; }
			if (S.v[2][i] == S.v[3][i] && S.v[3][i] == S.v[4][i] && S.v[2][i] != 0) { Delete[2][i] = true; Delete[3][i] = true; Delete[4][i] = true; }
		}

		// 消す処理
		int NewScore = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (Delete[i][j] == true) { NewScore += Score[S.v[i][j]]; S.v[i][j] = 0; }
			}
		}
		CurrentScore += NewScore * BonusScore;
		if (NewScore == 0) break;

		// 落ちる処理
		for (int k = 0; k < 5; k++) {
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 5; j++) {
					if (S.v[i + 1][j] == 0 && S.v[i][j] != 0) swap(S.v[i + 1][j], S.v[i][j]);
				}
			}
		}
	}

	// 答えを返す
	return CurrentScore;
}

// 全探索
int Solve(int dep, int px, int py, State S) {
	if (dep == 0) return CalculateScore(S);

	// 再帰呼び出し
	int Max = CalculateScore(S);
	for (int i = 0; i < 4; i++) {
		int ex = px + dx[i];
		int ey = py + dy[i];
		if (ex < 0 || ey < 0 || ex > 4 || ey > 4) continue;
		State T = S; swap(T.v[px][py], T.v[ex][ey]);
		int ret = Solve(dep - 1, ex, ey, T);
		Max = max(Max, ret);
	}

	// 答えを返す
	return Max;
}

int main() {
	while (true) {
		// Step 1. Input
		int N; cin >> N; if (N == -1) break;
		State S;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) cin >> S.v[i][j];
		}
		for (int i = 1; i <= 5; i++) cin >> Score[i];
		
		// Step 2. Brute Force
		int Answer = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				Answer = max(Answer, Solve(N, i, j, S));
			}
		}

		// Step 3. Output
		cout << Answer << endl;
	}
	return 0;
}
accuracy: 0.7142857142857143
time_ms: 50
memory_kb: 3424
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const int dx[4] = { 1, 0, -1, 0 };
const int dy[4] = { 0, 1, 0, -1 };
vector<pair<int, int>> path;

struct State {
	int ball[5][5];
};

int GetScore(State G, vector<int> Score) {
	int TotalScore = 0;

	// Simulation
	for (int t = 1; t <= 10000; t++) {
		vector<vector<bool>> Del(5, vector<bool>(5, false));
		for (int i = 0; i < 5; i++) {
			if (G.ball[i][0] == G.ball[i][1] && G.ball[i][1] == G.ball[i][2]) { Del[i][0] = true; Del[i][1] = true; Del[i][2] = true; }
			if (G.ball[i][1] == G.ball[i][2] && G.ball[i][2] == G.ball[i][3]) { Del[i][1] = true; Del[i][2] = true; Del[i][3] = true; }
			if (G.ball[i][2] == G.ball[i][3] && G.ball[i][3] == G.ball[i][4]) { Del[i][2] = true; Del[i][3] = true; Del[i][4] = true; }
		}
		for (int i = 0; i < 5; i++) {
			if (G.ball[0][i] == G.ball[1][i] && G.ball[1][i] == G.ball[2][i]) { Del[0][i] = true; Del[1][i] = true; Del[2][i] = true; }
			if (G.ball[1][i] == G.ball[2][i] && G.ball[2][i] == G.ball[3][i]) { Del[1][i] = true; Del[2][i] = true; Del[3][i] = true; }
			if (G.ball[2][i] == G.ball[3][i] && G.ball[3][i] == G.ball[4][i]) { Del[2][i] = true; Del[3][i] = true; Del[4][i] = true; }
		}
		int new_score = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (Del[i][j] == true) { new_score += t * Score[G.ball[i][j]]; G.ball[i][j] = 0; }
			}
		}
		if (new_score == 0) break;

		// Falling
		for (int j = 0; j < 5; j++) {
			vector<int> vec;
			for (int i = 4; i >= 0; i--) {
				if (G.ball[i][j] >= 1) vec.push_back(G.ball[i][j]);
			}
			for (int i = 0; i < 5; i++) G.ball[i][j] = 0;
			for (int i = 0; i < vec.size(); i++) G.ball[4 - i][j] = vec[i];
		}
		TotalScore += new_score;
	}

	// Return
	return TotalScore;
}

int dfs(int rem, int px, int py, State S, vector<int> Score) {
	if (rem == 0) {
		int ret = GetScore(S, Score);
		return ret;
	}
	int Return = GetScore(S, Score);

	// Tansaku
	for (int i = 0; i < 4; i++) {
		int ex = px + dx[i];
		int ey = py + dy[i];
		if (ex < 0 || ey < 0 || ex >= 5 || ey >= 5) continue;
		State T = S;
		path.push_back(make_pair(ex, ey));
		swap(T.ball[px][py], T.ball[ex][ey]);
		int ret = dfs(rem - 1, ex, ey, T, Score);
		Return = max(Return, ret);
		path.pop_back();
	}

	// Return
	return Return;
}

int main() {
	while (true) {
		int N;
		State S;
		vector<int> Score(6, 0);

		// Step 1. Input
		cin >> N; if (N == -1) break;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) cin >> S.ball[i][j];
		}
		for (int i = 1; i <= 5; i++) cin >> Score[i];

		// Step 2. Brute Force
		int Answer = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				path.push_back(make_pair(i, j));
				int ret = dfs(N, i, j, S, Score);
				Answer = max(Answer, ret);
				path.clear();
			}
		}

		// Step 3. Output
		cout << Answer << endl;
	}
	return 0;
}
accuracy: 0.7142857142857143
time_ms: 80
memory_kb: 3360
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const int dx[4] = { 1, 0, -1, 0 };
const int dy[4] = { 0, 1, 0, -1 };
vector<pair<int, int>> path;

struct State {
	int ball[5][5];
};

int GetScore(State G, vector<int> Score) {
	int TotalScore = 0;

	// Simulation
	for (int t = 1; t <= 10000; t++) {
		vector<vector<bool>> Del(5, vector<bool>(5, false));
		for (int i = 0; i < 5; i++) {
			if (G.ball[i][0] == G.ball[i][1] && G.ball[i][1] == G.ball[i][2]) { Del[i][0] = true; Del[i][1] = true; Del[i][2] = true; }
			if (G.ball[i][1] == G.ball[i][2] && G.ball[i][2] == G.ball[i][3]) { Del[i][1] = true; Del[i][2] = true; Del[i][3] = true; }
			if (G.ball[i][2] == G.ball[i][3] && G.ball[i][3] == G.ball[i][4]) { Del[i][2] = true; Del[i][3] = true; Del[i][4] = true; }
		}
		for (int i = 0; i < 5; i++) {
			if (G.ball[0][i] == G.ball[1][i] && G.ball[1][i] == G.ball[2][i]) { Del[0][i] = true; Del[1][i] = true; Del[2][i] = true; }
			if (G.ball[1][i] == G.ball[2][i] && G.ball[2][i] == G.ball[3][i]) { Del[1][i] = true; Del[2][i] = true; Del[3][i] = true; }
			if (G.ball[2][i] == G.ball[3][i] && G.ball[3][i] == G.ball[4][i]) { Del[2][i] = true; Del[3][i] = true; Del[4][i] = true; }
		}
		int new_score = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (Del[i][j] == true) { new_score += t * Score[G.ball[i][j]]; G.ball[i][j] = 0; }
			}
		}
		if (new_score == 0) break;
		for (int k = 0; k < 5; k++) {
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 5; j++) {
					if (G.ball[i + 1][j] == 0 && G.ball[i][j] != 0) swap(G.ball[i + 1][j], G.ball[i][j]);
				}
			}
		}
		TotalScore += new_score;
	}

	// Return
	return TotalScore;
}

int dfs(int rem, int px, int py, State S, vector<int> Score) {
	if (rem == 0) {
		int ret = GetScore(S, Score);
		return ret;
	}
	int Return = GetScore(S, Score);

	// Tansaku
	for (int i = 0; i < 4; i++) {
		int ex = px + dx[i];
		int ey = py + dy[i];
		if (ex < 0 || ey < 0 || ex >= 5 || ey >= 5) continue;
		State T = S;
		path.push_back(make_pair(ex, ey));
		swap(T.ball[px][py], T.ball[ex][ey]);
		int ret = dfs(rem - 1, ex, ey, T, Score);
		Return = max(Return, ret);
		path.pop_back();
	}

	// Return
	return Return;
}

int main() {
	while (true) {
		int N;
		State S;
		vector<int> Score(6, 0);

		// Step 1. Input
		cin >> N; if (N == -1) break;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) cin >> S.ball[i][j];
		}
		for (int i = 1; i <= 5; i++) cin >> Score[i];

		// Step 2. Brute Force
		int Answer = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				path.push_back(make_pair(i, j));
				int ret = dfs(N, i, j, S, Score);
				Answer = max(Answer, ret);
				path.clear();
			}
		}

		// Step 3. Output
		cout << Answer << endl;
	}
	return 0;
}
accuracy: 0.7142857142857143
time_ms: 50
memory_kb: 3356
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const int dx[4] = { 1, 0, -1, 0 };
const int dy[4] = { 0, 1, 0, -1 };

struct State {
	int ball[5][5];
};

int GetScore(State G, vector<int> Score) {
	int TotalScore = 0;

	// Simulation
	for (int t = 1; t <= 10; t++) {
		vector<vector<bool>> Del(5, vector<bool>(5, false));
		for (int i = 0; i < 5; i++) {
			if (G.ball[i][0] == G.ball[i][1] && G.ball[i][1] == G.ball[i][2]) { Del[i][0] = true; Del[i][1] = true; Del[i][2] = true; }
			if (G.ball[i][1] == G.ball[i][2] && G.ball[i][2] == G.ball[i][3]) { Del[i][1] = true; Del[i][2] = true; Del[i][3] = true; }
			if (G.ball[i][2] == G.ball[i][3] && G.ball[i][3] == G.ball[i][4]) { Del[i][2] = true; Del[i][3] = true; Del[i][4] = true; }
		}
		for (int i = 0; i < 5; i++) {
			if (G.ball[0][i] == G.ball[1][i] && G.ball[1][i] == G.ball[2][i]) { Del[0][i] = true; Del[1][i] = true; Del[2][i] = true; }
			if (G.ball[1][i] == G.ball[2][i] && G.ball[2][i] == G.ball[3][i]) { Del[1][i] = true; Del[2][i] = true; Del[3][i] = true; }
			if (G.ball[2][i] == G.ball[3][i] && G.ball[3][i] == G.ball[4][i]) { Del[2][i] = true; Del[3][i] = true; Del[4][i] = true; }
		}
		int new_score = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (Del[i][j] == true) { new_score += t * Score[G.ball[i][j]]; G.ball[i][j] = 0; }
			}
		}
		if (new_score == 0) break;
		for (int k = 0; k < 5; k++) {
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 5; j++) {
					if (G.ball[i + 1][j] == 0 && G.ball[i][j] != 0) swap(G.ball[i + 1][j], G.ball[i][j]);
				}
			}
		}
		TotalScore += new_score;
	}

	// Return
	return TotalScore;
}

int dfs(int rem, int px, int py, State S, vector<int> Score) {
	if (rem == 0) return GetScore(S, Score);
	int Return = GetScore(S, Score);

	// Tansaku
	for (int i = 0; i < 4; i++) {
		int ex = px + dx[i];
		int ey = py + dy[i];
		if (ex < 0 || ey < 0 || ex >= 5 || ey >= 5) continue;
		State T = S;
		swap(T.ball[px][py], T.ball[ex][ey]);
		int ret = dfs(rem - 1, ex, ey, T, Score);
		Return = max(Return, ret);
	}

	// Return
	return Return;
}

int main() {
	while (true) {
		int N;
		State S;
		vector<int> Score(6, 0);

		// Step 1. Input
		cin >> N; if (N == -1) break;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) cin >> S.ball[i][j];
		}
		for (int i = 1; i <= 5; i++) cin >> Score[i];

		// Step 2. Brute Force
		int Answer = 0;
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				int ret = dfs(N, i, j, S, Score);
				Answer = max(Answer, ret);
			}
		}

		// Step 3. Output
		cout << Answer << endl;
	}
	return 0;
}
accuracy: 0.7142857142857143
time_ms: 50
memory_kb: 3424
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
#include <array>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <tuple>
#include <bitset>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>

typedef std::array<std::array<char, 5>, 5> State;
struct Coordinate {
	int x, y;
	Coordinate operator+(const Coordinate a) const {
		return { x + a.x, y + a.y };
	}
};

constexpr std::array<Coordinate, 4> neighbor = { Coordinate{1, 0}, Coordinate{-1,0}, Coordinate{0,1}, Coordinate{0,-1} };
void drop(State& state) {
	for (auto j = 0; j < 5; ++j) {
		int count = 0;
		for (auto i = 4; i >= 0; --i) {
			if (state[i][j] == -1) ++count;
			else if (count != 0) {
				state[i + count][j] = state[i][j];
				state[i][j] = -1;
			}
		}
	}
}
std::array<char, 5> erase_block(State & state) {
	std::stack<Coordinate> horizontal, vertical;
	for (auto i = 0; i < 5; ++i) {
		for (auto j = 0; j < 3; ++j) {
			if (state[i][j] != -1) {
				auto is_seq{ true };
				for (auto c = 1; c < 3; ++c) {
					if (state[i][j] != state[i][j + c]) is_seq = false;
				}
				if (is_seq) horizontal.push({ j, i });
			}
			if (state[j][i] != -1) {
				auto is_seq{ true };
				for (auto c = 1; c < 3; ++c) {
					if (state[j][i] != state[j + c][i]) is_seq = false;
				}
				if (is_seq) vertical.push({ i, j });
			}
		}
	}
	std::array<char, 5> result{ 0,0,0,0,0 };
	while (!horizontal.empty()) {
		auto top = horizontal.top(); horizontal.pop();
		for (auto c = 0; c < 3; ++c) {
			if (state[top.y][top.x + c] != -1) result[state[top.y][top.x + c] - 1]++;
			state[top.y][top.x + c] = -1;
		}
	}
	while (!vertical.empty()) {
		auto top = vertical.top(); vertical.pop();
		for (auto c = 0; c < 3; ++c) {
			if (state[top.y + c][top.x] != -1) result[state[top.y + c][top.x] - 1]++;
			state[top.y + c][top.x] = -1;
		}
	}
	return result;
}
bool is_valid(Coordinate position, int order, const int length) {
	auto next = position;
	for (auto i = 0; i < length; ++i) {
		next = next + neighbor[order % 4];
		if (next.y < 0 || next.y >= 5 || next.x < 0 || next.x >= 5) return false;
		order /= 4;
	}
	return true;
}
State swap(const State& state, Coordinate position, int order, const int length) {
	auto copy = state;
	for (auto i = 0; i < length; ++i) {
		auto next = position + neighbor[order % 4];
		auto temp = copy[position.y][position.x];
		copy[position.y][position.x] = copy[next.y][next.x];
		copy[next.y][next.x] = temp;
		position = next;
		order /= 4;
	}
	return copy;
}

int main() {
	while (true) {
		int n; std::cin >> n; if (n == -1) break;
		State state; for (auto& line : state) for (auto& a : line) {
			std::cin >> a;
			a -= '0';
		}
		std::array<int, 5> score; for (auto& s : score) std::cin >> s;
		int max_score = 0;
		for (auto length = 0; length <= n; ++length) {
			for (auto order = 0; order < (1 << (length * 2)); ++order) {
				for (auto y = 0; y < 5; ++y) for (auto x = 0; x < 5; ++x) if (is_valid({ x, y }, order, length)) {
					auto s = swap(state, { x, y }, order, length);
					int sum_score{ 0 };
					int bonus{ 1 };
					while (true) {
						auto erased = erase_block(s);
						if (std::count(erased.begin(), erased.end(), 0) == 5) break;
						for (auto i = 0; i < 5; ++i) {
							sum_score += score[i] * erased[i] * bonus;
						}
						++bonus;
						drop(s);
					}
					max_score = std::max(max_score, sum_score);
				}
			}
		}
		std::cout << max_score << std::endl;

	}
}
accuracy: 1
time_ms: 90
memory_kb: 3120
final_rank: 8

code_snippet: #include <vector>
#include <set>
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;

using vector2D = vector< vector<int> >;
const int B = 5;
int N;

int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};

struct State {
  vector2D board;
  int x, y;
};

vector<int> score;
long long int solve(vector2D board) {
  long long int ret = 0, bonus = 1;
  for(; ; bonus++) {
    bool update = false;
    vector2D checked(B, vector<int>(B));
    
    for(int i=0; i<B; i++) {
      for(int j=0; j<B; j++) {
        // empty
        if(board[i][j] == 0) continue;

        vector<int> dirs = {2, 0};
        for(auto k : dirs) {
          // right or down
          int cons = 0;
          int nx = i, ny = j;
          while(nx < B && ny < B) {
            if(board[nx][ny] != board[i][j]) break;
            cons++;
            nx += dx[k], ny += dy[k];
          }
          if(cons >= 3) {
            update = true;
            nx = i, ny = j;
            while(nx < B && ny < B) {
              if(board[nx][ny] != board[i][j]) break;
              checked[nx][ny] = 1;
              nx += dx[k], ny += dy[k];
            }
          }
        }
      }
    }
    // printf("bonus = %lld, update = %d\n", bonus, update);
    if(!update) break;

    for(int i=0; i<B; i++) {
      for(int j=0; j<B; j++) {
        // empty or no change
        if(board[i][j] == 0 || checked[i][j] == false) continue;

        int col = board[i][j] - 1;
        board[i][j] = 0;
        ret += bonus * score[col];
      }
    }

    // blockfall
    for(int i=B-1; i>=0; i--) {
      for(int j=0; j<B; j++) {
        int row = i;
        for(; row < B-1 && board[row+1][j] == 0; row++) {
          swap(board[row][j], board[row+1][j]);
        }
      }
    }
  }
  
  return ret;
}

int main() {
  while(cin >> N, N >= 0) {
    vector2D board(B, vector<int>(B));
    for(int i=0; i<B; i++) {
      for(int j=0; j<B; j++) {
        cin >> board[i][j];
      }
    }
    score.clear();
    for(int i=0; i<B; i++) {
      int val; cin >> val;
      score.push_back(val);
    }

    set<vector2D> cand;
    cand.insert(board);
    queue<State> que;
    for(int i=0; i<B; i++) {
      for(int j=0; j<B; j++) {
        que.push(State{board, i, j});
      }
    }

    // printf("enumerate begin\n");
    for(int i=0; i<N; i++) {
      queue<State> nxt;
      while(que.size()) {
        State cur = que.front(); que.pop();
        vector2D board = cur.board;
        int x = cur.x, y = cur.y;

        for(int k=0; k<4; k++) {
          int nx = x + dx[k], ny = y + dy[k];
          if(nx < 0 || nx >= B || ny < 0 || ny >= B) continue;
          swap(board[x][y], board[nx][ny]);
          nxt.push(State{board, nx, ny});
          cand.insert(board);
          swap(board[x][y], board[nx][ny]);
        }
      }
      swap(nxt, que);
    }
    // printf("enumerate end\n");

    long long int ans = 0;
    for(auto b : cand) {
      ans = max(ans, solve(b));
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 7488
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int H = 5, W = 5;
int GetID(int x, int y) { return y * W + x; }
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};

int n, a[25], score[6];

bool fall(int b[]) {
	bool ret = false;
	for (int x=0; x<5; ++x) {
		for (int y=3; y>=0; --y) {
			if (b[GetID(x, y)] != -1) {
				int cy = y;
				while (cy < 4 && b[GetID(x, cy+1)] == -1) {
					ret = true;
					swap(b[GetID(x, cy)], b[GetID(x, cy+1)]);
					++cy;
				}
			}
		}
	}
	return ret;
}

int vanish(int b[], int bonus) {
	bool flag[25];
	memset(flag, false, sizeof(flag));
	for (int y=0; y<5; ++y) for (int x=0; x<5; ++x) {
		if (y > 0 && y < 4 && b[GetID(x, y-1)] == b[GetID(x, y)] && b[GetID(x, y)] == b[GetID(x, y+1)]) {
			flag[GetID(x, y-1)] = flag[GetID(x, y)] = flag[GetID(x, y+1)] = true;
		}
		if (x > 0 && x < 4 && b[GetID(x-1, y)] == b[GetID(x, y)] && b[GetID(x, y)] == b[GetID(x+1, y)]) {
			flag[GetID(x-1, y)] = flag[GetID(x, y)] = flag[GetID(x+1, y)] = true;
		}
	}
	
	int ret = 0;
	for (int y=0; y<5; ++y) for (int x=0; x<5; ++x) {
		if (flag[GetID(x, y)]) {
			ret += score[b[GetID(x, y)]] * bonus;
			b[GetID(x, y)] = -1;
		}
	}
	return ret;
}

void print(int b[]) {
	for (int y=0; y<5; ++y) for (int x=0; x<5; ++x) cerr << b[GetID(x,y)] << (x<4 ? " " : "\n");
	cerr << "-----" << endl;
}

int calcScore() {
	int b[25], ret = 0, bonus = 1;
	for (int i=0; i<25; ++i) b[i] = a[i];
	do {
		ret += vanish(b, bonus);
		++bonus;
		//print(b);
	} while (fall(b));
	return ret;
}

int rec(int x, int y) {
	if (n == 0) return calcScore();
	int ret = calcScore();
	for (int d=0; d<4; ++d) {
		int nx = x + dx[d], ny = y + dy[d];
		if (nx < 0 || nx >= 5 || ny < 0 || ny >= 5) continue;
		--n;
		swap(a[GetID(x, y)], a[GetID(nx, ny)]);
		ret = max(ret, rec(nx, ny));
		++n;
		swap(a[GetID(x, y)], a[GetID(nx, ny)]);
	}
	return ret;
}

int main() {
	while (cin >> n, n != -1) {
		for (int y=0; y<5; ++y) for (int x=0; x<5; ++x) cin >> a[GetID(x, y)];
		for (int i=0; i<5; ++i) cin >> score[i+1];
		int ans = 0;
		for (int y=0; y<5; ++y) for (int x=0; x<5; ++x) ans = max(ans, rec(x, y));
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 20
memory_kb: 3116
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
int n,score[5],result,r0,bonus;
vector <vector<int> > a(5,vector<int>(5)),check(5,vector<int>(5));

bool in(int y,int x){
  if(-1<y&&y<5 && -1<x&&x<5) return 1;
  else return 0;
}

bool sc(){
  vector <vector<int> > t0(5,vector<int>(5,0));
  for(int i=0;i<5;i++){
    int j=0;
    for(;j<5;){
      int pj=j;
      for(;j+1<5&&check[i][j]==check[i][j+1];) j++;
      if(j+1-pj>=3) for(;pj<=j;pj++) t0[i][pj]=1;
      j++;
    }
  }
  for(int j=0;j<5;j++){
    int i=0;
    for(;i<5;){
      int pi=i;
      for(;i+1<5&&check[i][j]==check[i+1][j];) i++;
      if(i+1-pi>=3) for(;pi<=i;pi++) t0[pi][j]=1;
      i++;
    }
  }
  int flag=0;
  for(int i=0;i<5;i++) for(int j=0;j<5;j++){
      if(t0[i][j]&&check[i][j]){
	r0+=t0[i][j]*bonus*score[check[i][j]-1];
	check[i][j]=0,flag++;
      }
    }
  
  for(int j=0;j<5;j++){
    int ni=5;
    for(int i=4;i>-1;i--){
      if(check[i][j]) check[--ni][j]=check[i][j];
    }
    for(int i=0;i<ni;i++) check[i][j]=0;
  }
  // cout<<r0<<endl;
  
  return flag;

}

void dfs(int sw,int y,int x,int d){

  //  cout<<sw<<" "<<y<<" "<<x<<" "<<d<<endl;
  
  if(sw>n) return;
  check=a;
  r0=0;
  bonus=1;
  while(sc()) bonus++; 
  result=max(result,r0);
  
  for(int k=0;k<4;k++){
    if(~d&&(d+2)%4==k) continue;
    int ny=y+dy[k],nx=x+dx[k];
    if(!in(ny,nx)) continue;

    swap(a[y][x],a[ny][nx]);
    dfs(sw+1,ny,nx,k);
    swap(a[y][x],a[ny][nx]);
  }
  
}

signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);

  for(;cin>>n;){
    if(n==-1) break;
    result=0;
    for(int i=0;i<5;i++) for(int j=0;j<5;j++) cin>>a[i][j];
    for(int i=0;i<5;i++) cin>>score[i];
    
    for(int i=0;i<5;i++) for(int j=0;j<5;j++) dfs(0,i,j,-1);
    
    cout<<result<<endl;
  }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3148
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define int long long
#define double long double
using namespace std;
const int N = 100010;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
typedef pair<int,int> P;
typedef long long ll;
ostream& operator<<(ostream& o,P p){
  return o<<"("<<p.first<<","<<p.second<<")";
}
istream& operator>>(istream& i,P &p){return i>>p.first>>p.second;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(auto &t:a)cin>>t;return i;}
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T> void prArr(T a,string s=" "){int i=0;for(auto t:a)cout<<(i++?s:"")<<t;cout<<endl;}


int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
vector<int> score;

int calcScore(const vector<vector<int> > &mp, int bonus){
  
  auto okw=[&](int i,int j){
    if(j + 2 >= 5) return false;
    if(mp[i][j] == -1) return false;
    return mp[i][j] == mp[i][j+1] && mp[i][j] == mp[i][j+2];
  };
  
  auto okh=[&](int i,int j){
    if(i + 2 >= 5) return false;
    if(mp[i][j] == -1) return false;
    return mp[i][j] == mp[i+1][j] && mp[i][j] == mp[i+2][j];
  };
  
  int flag = 0;
  vector<vector<int> > res = mp;
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++){
      if(okw(i,j)) res[i][j] = res[i][j+1] = res[i][j+2] = -2;
      if(okh(i,j)) res[i][j] = res[i+1][j] = res[i+2][j] = -2;
    }
  
  int block = 0;
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++)
      if(res[i][j] == -2){
	assert(mp[i][j] >= 0);
	flag = 1;
	res[i][j] = -1;
	block += score[mp[i][j] - 1];
      }
  
  for(int j=0;j<5;j++)
    for(int k=0;k<5;k++)
      for(int i = 0; i < 5-1; i++)
	if(res[i][j] == -1) swap(res[i][j],res[i+1][j]);

  int ans = bonus * block;
  // if(bonus == 2) cout<<"2="<<ans<<endl;
  if(flag) ans += calcScore(res,bonus+1);
  return ans;
}

int dfs(int i,int j,int n,vector<vector<int> > mp){
  
  
  if(n == 0) return calcScore(mp,1);
  

  int res = calcScore(mp,1);
  for(int k=0;k<4;k++){
    int ni = i + dy[k];
    int nj = j + dx[k];
    if(ni < 0 || nj < 0 || ni >= 5 || nj >= 5) continue;
    swap(mp[i][j], mp[ni][nj]);
    res = max(res,dfs(ni,nj,n-1,mp));
    swap(mp[i][j], mp[ni][nj]);
  }
  return res;
}

signed main(){
  while(1){
    int n;
    cin>>n;
    if(n == -1) break;
    vector<vector<int> > A(5,vector<int>(5));
    for(int i=0;i<5;i++)
      for(int j=0;j<5;j++) cin>>A[4-i][j];

    score.clear();
    score.resize(5);
    for(int i=0;i<5;i++) cin>>score[i];
    
    int ans = -INF;
    for(int i=0;i<5;i++)
      for(int j=0;j<5;j++) Max(ans,dfs(i,j,n,A));
    
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3176
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

int n, ans, point[5];

void sim(vector<vector<int> > A){
  
  int sum = 0, x = 1, update = 1;
  
  int used[5][5];
  
  while(update){
    
    update = 0;
    
    memset( used, 0, sizeof(used) );
    
    for(int i=0;i<5;i++){
      
      for(int j=1;j<4;j++){
	
	if( A[i][j] == 0 ) continue;
	
	if( A[i][j-1] == A[i][j] && A[i][j] == A[i][j+1] ){
	  used[i][j-1] = 1;
	  used[i][j] = 1;
	  used[i][j+1] = 1;
	}
		
      }

    }

    for(int i=1;i<4;i++){

      for(int j=0;j<5;j++){
	
	if( A[i][j] == 0 ) continue;
	
    	if( A[i-1][j] == A[i][j] && A[i][j] == A[i+1][j] ){
	  used[i-1][j] = 1;
	  used[i][j] = 1;
	  used[i+1][j] = 1;
	}
	
      }
      
    }

    int cnt[5] = {};
    
    for(int i=0;i<5;i++){
      
      for(int j=0;j<5;j++){
	
	if( used[i][j] ){
	  cnt[A[i][j]-1]++;
	  A[i][j] = 0;
	  update = 1;
	}
	
      }
      
    }
    /*    
    for(int i=0;i<5;i++){
      for(int j=0;j<5;j++) cout<<A[i][j]<<' ';
      cout<<endl;
    }
    */
    
    int update2 = 1;

    while(update2){
      
      update2 = 0;
      
      for(int i=0;i<5;i++){
	
	for(int j=4;j>=1;j--){
	  
	  if( A[j][i] == 0 && A[j-1][i] != 0 ){
	    
	    swap( A[j][i], A[j-1][i] );
	    
	    update2 = 1;
	    
	  }
	  
	}
	
      }

    }
       
    for(int i=0;i<5;i++){
      sum += x * cnt[i] * point[i];
    }
    
    x++;
    
  }
  
  ans = max( ans, sum );
  
}

int dy[4] = {-1,0,1,0};
int dx[4] = {0,1,0,-1};

void dfs(int y, int x, vector<vector<int> > A, int cnt){
  
  if( n < cnt ) return;
  
  sim(A);
  
  for(int i=0;i<4;i++){
    
    int ny = y + dy[i], nx = x + dx[i];

    if( ny < 0 || nx < 0 || 5 <= ny || 5 <= nx ) continue;
    
    swap( A[y][x], A[ny][nx] );
    
    dfs( ny, nx, A, cnt + 1 );

    swap( A[y][x], A[ny][nx] );
      
  }
  
}

int main(){
  
  while(1){
    
    cin>>n;
    
    if( n == -1 ) break;
    
    vector<vector<int> > A( 5, vector<int>(5) );
    
    for(int i=0;i<5;i++)
      for(int j=0;j<5;j++) cin>>A[i][j];
    
    for(int i=0;i<5;i++) cin>>point[i];
    
    ans = 0;
    
    for(int i=0;i<5;i++){
      
      for(int j=0;j<5;j++){
	
	dfs( i, j, A, 0 );
	
      }
      
    }
    
    cout << ans << endl;
    
  }
  
  return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3128
final_rank: 10

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	int table[5][5],rest;
};

int N,ans;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0},score[6];

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= 4 && col >= 0 && col <= 4)return true;
	else{
		return false;
	}
}

int calc(int table[5][5]){

	int ret = 0;

	int work[5][5],delete_num[6];
	bool delete_table[5][5];

	for(int row = 0; row < 5; row++){
		for(int  col = 0; col < 5; col++)work[row][col] = table[row][col];
	}

	int bonus = 1,delete_sum,tmp,count,tmp_row,tmp_col;

	while(true){

		delete_sum = 0;
		for(int i = 1; i <= 5; i++)delete_num[i] = 0;

		for(int row = 0; row < 5; row++){
			for(int col = 0; col < 5; col++)delete_table[row][col] = false;
		}

		for(int row = 0; row <= 4; row++){
			for(int col = 0; col <= 2; col++){
				if(delete_table[row][col] == true || work[row][col] == 0)continue;

				tmp_col = col;
				for(count = 0; tmp_col <= 4 && work[row][col] == work[row][tmp_col]; count++,tmp_col++);
				if(count >= 3){
					for(int i = 0; i < count; i++){
						delete_table[row][col+i] = true;
					}
				}
			}
		}

		for(int col = 0; col <= 4; col++){
			for(int row = 0; row <= 2; row++){
				if(delete_table[row][col] == true || work[row][col] == 0)continue;

				tmp_row = row;
				for(count = 0; tmp_row <= 4 && work[row][col] == work[tmp_row][col]; count++,tmp_row++);
				if(count >= 3){
					for(int i = 0; i < count; i++){
						delete_table[row+i][col] = true;
					}
				}
			}
		}

		for(int row = 0; row < 5; row++){
			for(int col = 0; col < 5; col++){
				if(delete_table[row][col]){
					delete_num[work[row][col]]++;
					delete_sum++;
					work[row][col] = 0;
				}
			}
		}

		for(int col = 0; col < 5; col++){
			for(int row = 4; row >= 1; row--){
				if(work[row][col] == 0){
					for(tmp = row-1; tmp >= 0; tmp--){
						if(work[tmp][col] != 0)break;
					}
					if(tmp == -1)break;

					work[row][col] = work[tmp][col];
					work[tmp][col] = 0;
				}
			}
		}

		if(delete_sum == 0)break;

		for(int i = 1; i <= 5; i++){
			ret += delete_num[i]*score[i]*bonus;
		}

		bonus++;
	}

	return ret;
}


void recursive(Info info,int row,int col){

	ans = max(ans,calc(info.table));

	if(info.rest == 0)return;

	int adj_row,adj_col;
	for(int i = 0; i < 4; i++){
		adj_row = row+diff_row[i];
		adj_col = col+diff_col[i];

		if(!rangeCheck(adj_row,adj_col))continue;

		Info new_info;
		for(int row = 0; row < 5; row++){
			for(int col = 0; col < 5; col++)new_info.table[row][col] = info.table[row][col];
		}
		swap(new_info.table[adj_row][adj_col],new_info.table[row][col]);
		new_info.rest = info.rest-1;
		recursive(new_info,adj_row,adj_col);
	}
}


void func(){

	Info first;
	for(int row = 0; row < 5; row++){
		for(int col = 0; col < 5; col++)scanf("%d",&first.table[row][col]);
	}

	for(int i = 1; i <= 5; i++)scanf("%d",&score[i]);

	first.rest = N;

	ans = 0;

	for(int row = 0; row < 5; row++){
		for(int col = 0; col < 5; col++)recursive(first,row,col);
	}

	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d",&N);
		if(N == -1)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3192
final_rank: 4

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;
typedef pair<int, bool>P;
 
int s[5], dx[]{ 1,-1,0,0, }, dy[]{ 0,0,1,-1 };
vector<vector<int>>a(5, vector<int>(5));
int Max,n;
void dfs(int x, int y, int c) {
	if(c==0||n%2!=0){
    vector<vector<P>>b(5, vector<P>(5));
    rep(i, 5)rep(j, 5)b[i][j].first = a[i][j];
    bool update = true;
    int p = 0;
    for (int v = 1; update; v++) {
        update = false;
        rep(i, 5) {
            int back = 0, cnt = 0;
            rep(j, b[i].size()) {
                if (back != b[i][j].first) {
                    if (cnt >= 3) {
                        for (int k = 1; k <= cnt; k++)
                            b[i][j - k].second = 1;
                    }
                    cnt = 0;
                }
                back = b[i][j].first; cnt++;
            }
            if (cnt >= 3) {
                for (int k = 1; k <= cnt; k++)
                    b[i][b[i].size() - k].second = 1;
            }
        }
        rep(i, 5) {
            int back = 0, cnt = 0;
            rep(j, 5) {
                if (b[j].size() <= i || back != b[j][i].first) {
                    if (cnt >= 3) {
                        for (int k = 1; k <= cnt; k++)
                            b[j - k][i].second = 1;
                    }
                    cnt = 0;
                }
                if (i < b[j].size()) {
                    back = b[j][i].first; cnt++;
                }
            }
            if (cnt >= 3) {
                for (int k = 1; k <= cnt; k++)b[5 - k][i].second = 1;
            }
        }
        rep(i, 5)rep(j, b[i].size()) {
            if (b[i][j].second == 1) {
                p += v*s[b[i][j].first];
                b[i].erase(b[i].begin() + j); update = true; j--;
            }
        }
    }
    Max = max(Max, p);}
    if (c == 0)return;
    rep(i, 4) {
        int nx = x + dx[i], ny = y + dy[i];
        if (0 <= nx&&nx < 5 && 0 <= ny&&ny < 5) {
            swap(a[x][y], a[nx][ny]);
            dfs(nx, ny, c - 1);
            swap(a[x][y], a[nx][ny]);
        }
    }
}
int main() {
    while (scanf("%d", &n), ~n) {
        Max = 0;
        rep(i, 5)rep(j, 5)scanf("%d", &a[j][i]), a[j][i]--;
        rep(i, 5)reverse(a[i].begin(), a[i].end());
        rep(i, 5)scanf("%d", &s[i]);
        rep(i, 5)rep(j, 5)dfs(i, j, n);
        printf("%d\n", Max);
    }
}
accuracy: 1
time_ms: 60
memory_kb: 3284
final_rank: 7

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
struct State { int x[5][5]; };
int n, b[6];
pair<State, int>del(State S) {
	bool used[5][5]; for (int i = 0; i < 25; i++)used[i / 5][i % 5] = false;
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 3; j++) {
			if (S.x[i][j] == S.x[i][j + 1] && S.x[i][j] == S.x[i][j + 2] && S.x[i][j] >= 1) {
				for (int k = j; k < j + 3; k++)used[i][k] = true;
			}
			if (S.x[j][i] == S.x[j + 1][i] && S.x[j][i] == S.x[j + 2][i] && S.x[j][i] >= 1) {
				for (int k = j; k < j + 3; k++)used[k][i] = true;
			}
		}
	}
	int cnt = 0, u = 0;
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 5; j++) { if (used[i][j] == true) { cnt += b[S.x[i][j]]; S.x[i][j] = 0; u++; } }
	}
	if (u == 0)cnt = -1;
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 4; j++) {
			for (int k = 0; k < 5; k++) {
				if (S.x[j][k] >= 1 && S.x[j + 1][k] == 0)swap(S.x[j][k], S.x[j + 1][k]);
			}
		}
	}
	return make_pair(S, cnt);
}
int dfs(State S, int depth, int cx, int cy) {
	if (depth == n) {
		int d = 1, c = 0;
		while (true) {
			pair<State, int>G = del(S);
			if (G.second == -1)return c;
			c += d*G.second; S = G.first; d++;
		}
	}
	int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 }, maxn = 0;
	for (int i = 0; i < 4; i++) {
		int ex = cx + dx[i], ey = cy + dy[i];
		if (ex < 0 || ex >= 5 || ey < 0 || ey >= 5)continue;
		State T = S; swap(T.x[ex][ey], T.x[cx][cy]);
		maxn = max(maxn, dfs(T, depth + 1, ex, ey));
	}
	return maxn;
}
int main() {
	while (true) {
		cin >> n; if (n == -1)break; State V;
		for (int i = 0; i < 25; i++)cin >> V.x[i / 5][i % 5];
		for (int i = 1; i <= 5; i++)cin >> b[i];
		int ret = 0; for (int i = 0; i < 25; i++) { for (int j = 0; j <= n; j++)ret = max(ret, dfs(V, j, i / 5, i % 5)); }
		cout << ret << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3088
final_rank: 5

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
struct State { int x[5][5]; };
int n, b[6];
pair<State, int>del(State S) {
	bool used[5][5]; for (int i = 0; i < 25; i++)used[i / 5][i % 5] = false;
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 3; j++) {
			if (S.x[i][j] == S.x[i][j + 1] && S.x[i][j] == S.x[i][j + 2] && S.x[i][j] >= 1) {
				for (int k = j; k < j + 3; k++)used[i][k] = true;
			}
			if (S.x[j][i] == S.x[j + 1][i] && S.x[j][i] == S.x[j + 2][i] && S.x[j][i] >= 1) {
				for (int k = j; k < j + 3; k++)used[k][i] = true;
			}
		}
	}
	int cnt = 0, u = 0;
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 5; j++) { if (used[i][j] == true) { cnt += b[S.x[i][j]]; S.x[i][j] = 0; u++; } }
	}
	if (u == 0)cnt = -1;
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 4; j++) {
			for (int k = 0; k < 5; k++) {
				if (S.x[j][k] >= 1 && S.x[j + 1][k] == 0)swap(S.x[j][k], S.x[j + 1][k]);
			}
		}
	}
	return make_pair(S, cnt);
}
int dfs(State S, int depth, int cx, int cy) {
	if (depth == n) {
		int d = 1, c = 0;
		State V1 = S;
		while (true) {
			pair<State, int>G = del(S);
			if (c == 69) {
				for (int i = 0; i < 5; i++) {
					for (int j = 0; j < 5; j++) {
						cout << V1.x[i][j] << ' ';
					}
					cout << endl;
				}
			}
			if (G.second == -1)return c;
			c += d*G.second; S = G.first; d++;
		}
	}
	int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 }, maxn = 0;
	for (int i = 0; i < 4; i++) {
		int ex = cx + dx[i], ey = cy + dy[i];
		if (ex < 0 || ex >= 5 || ey < 0 || ey >= 5)continue;
		State T = S; swap(T.x[ex][ey], T.x[cx][cy]);
		maxn = max(maxn, dfs(T, depth + 1, ex, ey));
	}
	return maxn;
}
int main() {
	while (true) {
		cin >> n; if (n == -1)break; State V;
		for (int i = 0; i < 25; i++)cin >> V.x[i / 5][i % 5];
		for (int i = 1; i <= 5; i++)cin >> b[i];
		int ret = 0; for (int i = 0; i < 25; i++) { for (int j = 0; j <= n; j++)ret = max(ret, dfs(V, j, i / 5, i % 5)); }
		cout << ret << endl;
	}
	return 0;
}
accuracy: 0.8571428571428571
time_ms: 50
memory_kb: 3100
final_rank: 15

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;
typedef pair<int, bool>P;

int s[5], dx[]{ 1,-1,0,0, }, dy[]{ 0,0,1,-1 };
vector<vector<int>>a(5, vector<int>(5));
int Max;
void dfs(int x, int y, int c) {
	vector<vector<P>>b(5, vector<P>(5));
	rep(i, 5)rep(j, 5)b[i][j].first = a[i][j];
	bool update = true;
	int p = 0;
	for (int v = 1; update; v++) {
		update = false;
		rep(i, 5) {
			int back = 0, cnt = 0;
			rep(j, b[i].size()) {
				if (back != b[i][j].first) {
					if (cnt >= 3) {
						for (int k = 1; k <= cnt; k++)
							b[i][j - k].second = 1;
					}
					cnt = 0;
				}
				back = b[i][j].first; cnt++;
			}
			if (cnt >= 3) {
				for (int k = 1; k <= cnt; k++)
					b[i][b[i].size() - k].second = 1;
			}
		}
		rep(i, 5) {
			int back = 0, cnt = 0;
			rep(j, 5) {
				if (b[j].size() <= i || back != b[j][i].first) {
					if (cnt >= 3) {
						for (int k = 1; k <= cnt; k++)
							b[j - k][i].second = 1;
					}
					cnt = 0;
				}
				if (i < b[j].size()) {
					back = b[j][i].first; cnt++;
				}
			}
			if (cnt >= 3) {
				for (int k = 1; k <= cnt; k++)b[5 - k][i].second = 1;
			}
		}
		rep(i, 5)rep(j, b[i].size()) {
			if (b[i][j].second == 1) {
				p += v*s[b[i][j].first];
				b[i].erase(b[i].begin() + j); update = true; j--;
			}
		}
	}
	Max = max(Max, p);
	if (c == 0)return;
	rep(i, 4) {
		int nx = x + dx[i], ny = y + dy[i];
		if (0 <= nx&&nx < 5 && 0 <= ny&&ny < 5) {
			swap(a[x][y], a[nx][ny]);
			dfs(nx, ny, c - 1);
			swap(a[x][y], a[nx][ny]);
		}
	}
}
int main() {
	int n;
	while (scanf("%d", &n), ~n) {
		Max = 0;
		rep(i, 5)rep(j, 5)scanf("%d", &a[j][i]), a[j][i]--;
		rep(i, 5)reverse(a[i].begin(), a[i].end());
		rep(i, 5)scanf("%d", &s[i]);
		rep(i, 5)rep(j, 5)dfs(i, j, n);
		printf("%d\n", Max);
	}
}
accuracy: 1
time_ms: 50
memory_kb: 3288
final_rank: 6

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"

vector<int>ss(5);
void  fall(vector<vector<int>>&field) {
	for (int t = 0; t < 5; ++t) {
		for (int y = 4; y > 0; --y) {
			for (int x = 0; x < 5; ++x) {
				if (field[y][x] == 0 && field[y - 1][x]) {
					swap(field[y][x], field[y - 1][x]);
				}
			}
		}
	}
}
int getscore(vector<vector<int>>field) {
	int bonus = 1;
	int ans = 0;
	int num = 10;
	while (num--) {

		vector<vector<int>>del(5, vector<int>(5));
		{
			for (int x = 0; x < 5; ++x) {
				for (int u = 0; u < 3; ++u) {
					int c = field[u][x];
					if (!c)continue;
					int num = 0;
					for (int y = u; y < 5; ++y) {
						if (field[y][x] == c) {
							num++;
						}
						else {
							break;
						}
					}
					if (num >= 3) {
						for (int y = u; y < u + num; ++y) {
							del[y][x] = true;
						}
					}
				}
			}
			for (int y = 0; y < 5; ++y) {
				for (int l = 0; l < 3; ++l) {
					int c = field[y][l];
					if (!c)continue;
					int num = 0;
					for (int x = l; x < 5; ++x) {
						if (field[y][x] == c) {
							num++;
						}
						else {
							break;
						}
					}
					if (num >= 3) {
						for (int x = l; x < l + num; ++x) {
							del[y][x] = true;
						}
					}
				}
			}
		}
		for (int y = 0; y < 5; ++y) {
			for (int x = 0; x < 5; ++x) {
				if (del[y][x]) {
					ans += ss[field[y][x]-1] * bonus;
					field[y][x] = 0;
				}
			}
		}
		fall(field);

		bonus++;
	}
	return ans;
}
int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,1,0,-1 };
int solve(vector<vector<int>>field, int rest,int x,int y) {
	int ans = getscore(field);
	if (rest) {
		for (int way = 0; way < 4; ++way) {
			int nx = x + dx[way];
			int ny = y + dy[way];
			if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5) {
				swap(field[y][x], field[ny][nx]);
				ans = max(ans, solve(field, rest - 1, nx, ny));
				swap(field[y][x], field[ny][nx]);
			}
		}
	}
	return ans;
}

int main() {
	while (1) {
		int N; cin >> N;
		if (N == -1)break;
		vector<vector<int>>field(5, vector<int>(5));
		for (int i = 0; i < 5; ++i) {
			for (int j = 0; j < 5; ++j) {
				int a; cin >> a; field[i][j] = a;
			}
		}
		for (int i = 0; i < 5; ++i) {
			cin >> ss[i];
		}
		int ans = 0;
		for (int i = 0; i < 5; ++i) {
			for (int j = 0; j < 5; ++j) {
				ans = max(ans, solve(field, N, i, j));
			}
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 3184
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef vector<int> Vec;
typedef vector<Vec> Mat;

Mat a(5, Vec(5));
int score[5];

const int dx[] = {-1, +0, +1, +0};
const int dy[] = {+0, -1, +0, +1};

bool inField(int x, int y)
{
    return (0 <= x && x < 5 && 0 <= y && y < 5);
}

int erase(Mat &m)
{
    bool e[5][5] = {{}};
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {                        
            if (m[i][j] == 0) {
                continue;
            }
            int cnt[2] = {1, 1};
            for (int k = 0; k < 4; k++) {
                int ni = i + dy[k];
                int nj = j + dx[k];
                while (inField(ni, nj) &&
                       m[i][j] == m[ni][nj]) {
                    ni += dy[k];
                    nj += dx[k];
                    ++cnt[k&1];
                }
            }
            if (cnt[0] >= 3 || cnt[1] >= 3) {
                e[i][j] = 1;
            }
        }
    }
    int point = 0;
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (e[i][j]) {
                point += score[m[i][j]-1];
                m[i][j] = 0;
            }
        }
    }
    return point;
}

void fall(Mat &m)
{
    for (int j = 0; j < 5; j++) {
        for (int i = 4; i >= 1; i--) {
            if (m[i][j] == 0) {                
                for (int k = i-1; k >= 0; k--) {
                    if (m[k][j] != 0) {
                        swap(m[i][j], m[k][j]);
                        break;
                    }
                }
            }
        }
    }
}

int get_point()
{
    Mat b = a;
    int point = 0, bp = 1;
    bool update = 1;
    
    while (update) {
        update = 0;        
        Mat nb = b;
        point += erase(nb) * bp++;
        fall(nb);
        if (nb != b) {        
            update = 1;
            b = nb;
        }
    }
    return point;
}

int dfs(int y, int x, int n, int p)    
{
    int point = get_point();
    if (n > 0) {
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (inField(nx, ny) && (p == -1 || (p + 2) % 4 != i)) {
                swap(a[ny][nx], a[y][x]);
                point = max(point, dfs(ny, nx, n-1, i));
                swap(a[ny][nx], a[y][x]);
            }        
        }
    }
    return point;
}

int main()
{
    int n;
    while (cin >> n, n != -1) {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                cin >> a[i][j];
            }
        }
    
        for (int i = 0; i < 5; i++) {
            cin >> score[i];
        }

        int max_point = 0;
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                max_point = max(max_point, dfs(i, j, n, -1));
            }
        }   
        cout << max_point << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3116
final_rank: 3

code_snippet: #include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <complex>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <assert.h>
#include <array>
#include <cstdio>
#include <cstring>
#include <random>
#include <functional>
#include <numeric>
#include <bitset>
#include <fstream>

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }

int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};
template<class T> constexpr bool in_range(T y, T x, T H, T W) { return 0<=y&&y<H&&0<=x&&x<W; }

int N;
int score[6];

void drop(vector<vector<int>>& a) {
  rep(j, 5) {
    deque<int> d;
    rep(i, 5) {
      if(a[i][j] != -1) {
        d.push_back(a[i][j]);
      }
    }

    int dsize = d.size();
    for(int i=4; i>=0 && !d.empty(); i--) {
      a[i][j] = d.back();
      d.pop_back();
    }
    rep(i, 5-dsize) {
      a[i][j] = -1;
    }
  }
}

int dist(vector<vector<int>> const& a, int num, int i, int j, int dy, int dx, int sum = 0) {
  i += dy, j += dx;
  if(!in_range(i, j, 5, 5)) return sum;
  if(a[i][j] != num) return sum;
  return dist(a, num, i, j, dy, dx, sum + 1);
}

int simulate(vector<vector<int>>& a) {
  int ret = 0;
  int bonus = 1;

  while(1) {
    set<int> used;
    rep(i, 5) rep(j, 5) {
      if(a[i][j] == -1) continue;
      int movel = dist(a, a[i][j], i, j, 0, -1);
      int mover = dist(a, a[i][j], i, j, 0, +1);
      int movet = dist(a, a[i][j], i, j, -1, 0);
      int moveb = dist(a, a[i][j], i, j, +1, 0);
      if(mover - movel + 1 >= 3) {
        REP(x, j - movel, j + mover + 1) {
          assert(a[i][x] != -1);
          assert(a[i][x] == a[i][j]);
          used.insert(i*5+x);
        }
      }
      if(moveb - movet + 1 >= 3) {
        REP(y, i - movet, i + moveb + 1) {
          assert(a[y][j] != -1);
          assert(a[y][j] == a[i][j]);
          used.insert(y*5+j);
        }
      }
    }

    for(auto && e: used) {
      ret += score[a[e/5][e%5]] * bonus;
      a[e/5][e%5] = -1;
    }

    bonus ++;
    if(!used.size()) break;
    drop(a);
  }

  return ret;
}



int dfs(vector<vector<int>> a, int y, int x, int idx = 0) {
  auto aa = a;
  int ret = simulate(a);
  if(idx < N) {
    rep(k, 4) {
      int ny = y + dy[k], nx = x + dx[k];
      if(!in_range(ny, nx, 5, 5)) continue;
      a = aa;
      swap(a[y][x], a[ny][nx]);
      maximize(ret, dfs(a, ny, nx, idx + 1));
    }
  }
  return ret;
}

int solve(vector<vector<int>>& a) {
  int ret = 0;
  rep(i, 5) rep(j, 5)  {
    maximize(ret, dfs(a, i, j));
  }
  return ret;
}

int main() {

  for(; cin >> N && N >= 0;) {
    vector<vector<int>> a(5, vector<int>(5));
    rep(i, 5) rep(j, 5) cin >> a[i][j];
    rep(i, 5) cin >> score[i+1];
    cout << solve(a) << endl;
  }
  
  return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 3156
final_rank: 12