public void setInput(int _X, int _R) { if (stepCnt >= stepMax) { return; } X = _X; R = _R; int[][] _pack; _pack = new int[packSize][]; for (int i = 0; i < packSize; i++) { _pack[i] = new int[packSize]; } // 回転を考慮 for (int i = 0; i < R; i++) { for (int j = 0; j < packSize; j++) { for (int k = 0; k < packSize; k++) { _pack[j][packSize - k - 1] = pack[stepCnt][k][j]; } } for (int j = 0; j < packSize; j++) { for (int k = 0; k < packSize; k++) { pack[stepCnt][j][k] = _pack[j][k]; } } } // グローバルマップにpackを追加する for (int i = 0; i < packSize; i++) { for (int j = 0; j < packSize; j++) { if (pack[stepCnt][j][i] > 0) { if ((X + i < 0 || X + i >= mapWidth)) { score = -100; return; } else { map[X + i][mapHeight + packSize - j] = pack[stepCnt][j][i]; } } } } // ■2. 終了条件を満たしていれば終了、そうでなければ 3 へ int chain; bool roop2_flag = true; for (chain = 1; roop2_flag; chain++) { roop2_flag = false; for (int i = 0; i < moveMap.Length; i++) { for (int j = 0; j < moveMap[i].Length; j++) { moveMap[i][j] = false; } } // ■3. 落下できるブロックがあれば全て落下 for (int i = 0; i < mapWidth; i++) { for (int j = 0; j < mapHeight + packSize + 1; j++) { if (map[i][j] == 0) { for (int k = j; k < mapHeight + packSize + 1; k++) { if (map[i][k] > 0) { map[i][j] = map[i][k]; map[i][k] = 0; moveMap[i][j] = true; int l = 1; int packSum = map[i][j]; while (true) { if (i - l < 0) { break; } if (map[i - l][j] == 0) { break; } packSum += map[i - l][j]; if (packSum > sumNum) { break; } moveMap[i - l][j] = true; } l = 1; packSum = map[i][j]; while (true) { if (j - l < 0) { break; } if (map[i][j - l] == 0) { break; } packSum += map[i][j - l]; if (packSum > sumNum) { break; } moveMap[i][j - l] = true; } l = 1; packSum = map[i][j]; while (true) { if (j - l < 0 || i - l < 0) { break; } if (map[i - l][j - l] == 0) { break; } packSum += map[i - l][j - l]; if (packSum > sumNum) { break; } moveMap[i - l][j - l] = true; } break; } } } } } for (int i = 0; i < mapWidth; i++) { if (map[i][mapHeight] > 0) { score = -1; return; } } // ■4. 消去できるブロックがあれば全て消去 int E = 0; // 消滅カウントE int C = chain; // チェインの数C int n = stepCnt / 100; // 現在のターン数を100で整数除算したn int P = (mapWidth <= 15) ? 25 : (mapWidth <= 20) ? 30 : 35; // ケースごとに与えられる値P for (int i = 0; i < mapWidth; i++) { for (int j = 0; j < mapHeight + packSize + 1; j++) { deleteMap[i][j] = false; } } // ray tracing for (int i = 0; i < mapWidth; i++) { for (int j = 0; j < mapHeight; j++) { int k = 0; int traceNum = 0; if (map[i][j] == sumNum) { deleteMap[i][j] = true; E++; } else { if (moveMap[i][j]) { // 縦方向に探索(height方向) while (true) { if (j + k >= mapHeight) { break; } traceNum += map[i][j + k]; if (map[i][j + k] == 0) { break; } if (traceNum > sumNum) { break; } if (traceNum == sumNum) { for (int l = 0; l <= k; l++) { deleteMap[i][j + l] = true; E++; } } k++; } k = 0; traceNum = 0; // 横方向に探索(width方向) while (true) { if (i + k >= mapWidth) { break; } traceNum += map[i + k][j]; if (map[i + k][j] == 0) { break; } if (traceNum > sumNum) { break; } if (traceNum == sumNum) { for (int l = 0; l <= k; l++) { deleteMap[i + l][j] = true; E++; } } k++; } k = 0; traceNum = 0; // 斜め方向に探索(右上がり) while (true) { if (i + k >= mapWidth || j + k >= mapHeight) { break; } traceNum += map[i + k][j + k]; if (map[i + k][j + k] == 0) { break; } if (traceNum > sumNum) { break; } if (traceNum == sumNum) { for (int l = 0; l <= k; l++) { deleteMap[i + l][j + l] = true; E++; } } k++; } k = 0; traceNum = 0; // 斜め方向に探索(右下がり) while (true) { if (i + k >= mapWidth || j - k < 0) { break; } traceNum += map[i + k][j - k]; if (map[i + k][j - k] == 0) { break; } if (traceNum > sumNum) { break; } if (traceNum == sumNum) { for (int l = 0; l <= k; l++) { deleteMap[i + l][j - l] = true; E++; } } k++; } } } } } // 削除する for (int i = 0; i < mapWidth; i++) { for (int j = 0; j < mapHeight; j++) { if (deleteMap[i][j]) { map[i][j] = 0; deleteMap[i][j] = false; roop2_flag = true; } } } // Console.WriteLine("E:" + E + " C:" + C + " n:" + n + " P:" + P); if (roop2_flag) { //if (C < Min(10,stepMax-stepCnt-1) && processDepth == 1) //{ // score -= E; // //if (score < -10) roop2_flag=false; //} //else //{ //score += Math.Pow(2, Min(C, P + n) - 1) * Max(1, C - (P + n) + 1) * E; score += Math.Pow(2, C - 1) * E; //} } // Console.WriteLine("Score : " + score); } int maxScore = 0; if (processDepth < processDepthConst) { for (int i = 0 - (packSize - 1); i < mapWidth - packSize + 1 + (packSize - 1); i++) { for (int j = 0; j < 4; j++) { Process p = new Process(debugFlag, mapWidth, mapHeight, packSize, sumNum, stepCnt + 1, stepMax, map, pack, processDepth + 1, Math); p.setInput(i, j); int _score = p.getScore(); if (maxScore < _score) { X = i; R = j; maxScore = _score; if (debugFlag) { scoreText = getScoreText(); } } } } if (debugFlag) { scoreText = "" + maxScore + "+" + scoreText; } score += maxScore; } if (debugFlag) { scoreText = (score - maxScore) + "+" + scoreText; } }
static int score = 0; // スコア static void Main(string[] args) { MyMath Math = new MyMath(); if (debugFlag) { using (StreamReader r = new StreamReader(@"sample_input.txt")) { string textLine = r.ReadLine(); string[] s = textLine.Split(' '); mapWidth = int.Parse(s[0]); mapHeight = int.Parse(s[1]); packSize = int.Parse(s[2]); sumNum = int.Parse(s[3]); stepMax = int.Parse(s[4]); map = new int[mapWidth][]; deleteMap = new bool[mapWidth][]; for (int i = 0; i < mapWidth; i++) { map[i] = new int[mapHeight + packSize + 1]; deleteMap[i] = new bool[mapHeight + packSize + 1]; } pack = new int[stepMax][][]; for (int i = 0; i < stepMax; i++) { pack[i] = new int[packSize][]; for (int j = 0; j < packSize; j++) { pack[i][j] = new int[packSize]; } } WriteLine(mapWidth + " " + mapHeight + " " + sumNum + " " + stepMax); // 確認出力 // パック入力 for (int i = 0; i < stepMax; i++) { for (int j = 0; j < packSize; j++) { textLine = r.ReadLine(); s = textLine.Split(' '); for (int k = 0; k < packSize; k++) { pack[i][j][k] = int.Parse(s[k]); } } r.ReadLine(); } } } else { // 入力 string textLine = System.Console.ReadLine(); string[] s = textLine.Split(' '); mapWidth = int.Parse(s[0]); mapHeight = int.Parse(s[1]); packSize = int.Parse(s[2]); sumNum = int.Parse(s[3]); stepMax = int.Parse(s[4]); map = new int[mapWidth][]; deleteMap = new bool[mapWidth][]; for (int i = 0; i < mapWidth; i++) { map[i] = new int[mapHeight + packSize + 1]; deleteMap[i] = new bool[mapHeight + packSize + 1]; } pack = new int[stepMax][][]; for (int i = 0; i < stepMax; i++) { pack[i] = new int[packSize][]; for (int j = 0; j < packSize; j++) { pack[i][j] = new int[packSize]; } } WriteLine(mapWidth + " " + mapHeight + " " + sumNum + " " + stepMax); // 確認出力 // パック入力 for (int i = 0; i < stepMax; i++) { for (int j = 0; j < packSize; j++) { textLine = System.Console.ReadLine(); s = textLine.Split(' '); for (int k = 0; k < packSize; k++) { pack[i][j][k] = int.Parse(s[k]); } } System.Console.ReadLine(); } } for (int stepCnt = 0; stepCnt < stepMax; stepCnt++) { // ■1. パックの回転、投下位置の指定 int X = 0; // パックの落とす位置 int R = 0; // パックを回転する回数 int maxScore = -1; for (int i = 0 - (packSize - 1); i < mapWidth - packSize + 1 + (packSize - 1); i++) { for (int j = 0; j < 4; j++) { Process p = new Process(debugFlag, mapWidth, mapHeight, packSize, sumNum, stepCnt, stepMax, map, pack, 1, Math); p.setInput(i, j); int _score = p.getScore(); WriteLine(i + "," + j + " : " + _score + " " + p.getScoreText()); if (maxScore < _score) { X = i; R = j; maxScore = _score; } } } WriteLine("(" + X + "," + R + ") " + maxScore); int[][] _pack; _pack = new int[packSize][]; for (int i = 0; i < packSize; i++) { _pack[i] = new int[packSize]; } // 回転を考慮 for (int i = 0; i < R; i++) { for (int j = 0; j < packSize; j++) { for (int k = 0; k < packSize; k++) { _pack[j][packSize - k - 1] = pack[stepCnt][k][j]; } } for (int j = 0; j < packSize; j++) { for (int k = 0; k < packSize; k++) { pack[stepCnt][j][k] = _pack[j][k]; } } } // グローバルマップにpackを追加する for (int i = 0; i < packSize; i++) { for (int j = 0; j < packSize; j++) { if (pack[stepCnt][j][i] > 0) { if ((X + i < 0 || X + i >= mapWidth)) { score = -100; return; } else { map[X + i][mapHeight + packSize - j] = pack[stepCnt][j][i]; } } } } // ■2. 終了条件を満たしていれば終了、そうでなければ 3 へ int chain; bool roop2_flag = true; for (chain = 1; roop2_flag; chain++) { roop2_flag = false; printMap(); WriteLine((chain == 0) ? "Pack入力" : "削除"); pause(); // ■3. 落下できるブロックがあれば全て落下 for (int i = 0; i < mapWidth; i++) { for (int j = 0; j < mapHeight + packSize + 1; j++) { if (map[i][j] == 0) { for (int k = j; k < mapHeight + packSize + 1; k++) { if (map[i][k] > 0) { map[i][j] = map[i][k]; map[i][k] = 0; break; } } } } } printMap(); WriteLine("落下"); pause(); // ■4. 消去できるブロックがあれば全て消去 int E = 0; // 消滅カウントE int C = chain; // チェインの数C int n = stepCnt / 100; // 現在のターン数を100で整数除算したn int P = (mapWidth <= 15)?25:(mapWidth <= 20)?30:35; // ケースごとに与えられる値P for (int i = 0; i < mapWidth; i++) { for (int j = 0; j < mapHeight + packSize + 1; j++) { deleteMap[i][j] = false; } } // ray tracing for (int i = 0; i < mapWidth; i++) { for (int j = 0; j < mapHeight; j++) { int k = 0; int traceNum = 0; if (map[i][j] == sumNum) { deleteMap[i][j] = true; E++; } else { // 縦方向に探索(height方向) while (true) { if (j + k >= mapHeight) { break; } traceNum += map[i][j + k]; if (map[i][j + k] == 0) { break; } if (traceNum > sumNum) { break; } if (traceNum == sumNum) { for (int l = 0; l <= k; l++) { deleteMap[i][j + l] = true; E++; } } k++; } k = 0; traceNum = 0; // 横方向に探索(width方向) while (true) { if (i + k >= mapWidth) { break; } traceNum += map[i + k][j]; if (map[i + k][j] == 0) { break; } if (traceNum > sumNum) { break; } if (traceNum == sumNum) { for (int l = 0; l <= k; l++) { deleteMap[i + l][j] = true; E++; } } k++; } k = 0; traceNum = 0; // 斜め方向に探索(右上がり) while (true) { if (i + k >= mapWidth || j + k >= mapHeight) { break; } traceNum += map[i + k][j + k]; if (map[i + k][j + k] == 0) { break; } if (traceNum > sumNum) { break; } if (traceNum == sumNum) { for (int l = 0; l <= k; l++) { deleteMap[i + l][j + l] = true; E++; } } k++; } k = 0; traceNum = 0; // 斜め方向に探索(右下がり) while (true) { if (i + k >= mapWidth || j - k < 0) { break; } traceNum += map[i + k][j - k]; if (map[i + k][j - k] == 0) { break; } if (traceNum > sumNum) { break; } if (traceNum == sumNum) { for (int l = 0; l <= k; l++) { deleteMap[i + l][j - l] = true; E++; } } k++; } } } } // 削除する for (int i = 0; i < mapWidth; i++) { for (int j = 0; j < mapHeight; j++) { if (deleteMap[i][j]) { map[i][j] = 0; deleteMap[i][j] = false; roop2_flag = true; } } } int s = 0; if (roop2_flag) { s = Math.Pow(2, Min(C, P + n) - 1) * Max(1, C - (P + n) + 1) * E; score += s; } WriteLine("S:" + s + " E:" + E + " C:" + C + " n:" + n + " P:" + P); WriteLine("Score : " + score); } if (maxChain < chain - 2) { maxChain = chain - 2; } printMap(); WriteLine("Turn : " + (stepCnt + 1)); WriteLine("Chain : " + (chain - 2)); WriteLine("Score : " + score); WriteLine("maxChain : " + maxChain); pause(); pause(); Console.WriteLine(X + " " + R); } WriteLine("end"); pause(); }