ぷよぷよを解く
人材募集企画 2011年版: 人生を書き換える者すらいた。 の【問題2】を解いてみました。30 分以上、1 時間未満でした。
using System; using System.Collections.Generic; using System.Linq; class Loc { public int Row { get; private set; } public int Col { get; private set; } public Loc(int row, int col) { Row = row; Col = col; } } class Puyo { static void Display(char[][] g) { for (int i = 0; i < g.Length; i++) { for (int j = 0; j < g[i].Length; j++) { Console.Write(g[i][j]); } Console.WriteLine(); } Console.WriteLine("------"); } static List<Loc> Group(Loc loc, char[][] g, int[,] used) { char puyo = g[loc.Row][loc.Col]; var group = new List<Loc>(); int rows = g.Length; int cols = g[0].Length; var q = new Queue<Loc>(); q.Enqueue(loc); while (q.Count > 0) { var p = q.Dequeue(); // 範囲外 if (!(0 <= p.Row && p.Row < rows && 0 <= p.Col && p.Col < cols)) continue; // ぷよが異なる if (puyo != g[p.Row][p.Col]) continue; // 探索済み if (used[p.Row, p.Col]++ > 0) continue; group.Add(p); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (Math.Abs(i) + Math.Abs(j) == 1) { q.Enqueue(new Loc(p.Row + i, p.Col + j)); } } } } return group; } static void Pack(char[][] g) { int rows = g.Length; int cols = g[0].Length; for (int c = 0; c < cols; c++) { var xs = new List<char>(); for (int r = rows-1; r >= 0; r--) { if (g[r][c] != ' ') { xs.Add(g[r][c]); } } for (int i = 0; i < rows; i++) { g[rows-i-1][c] = i < xs.Count ? xs[i] : ' '; } } } static void Solve(char[][] g) { int rows = g.Length; int cols = g[0].Length; bool update = true; while (update) { update = false; int[,] used = new int[rows, cols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (g[i][j] == ' ' || used[i, j] > 0) continue; var group = Group(new Loc(i, j), g, used); if (group.Count >= 4) { foreach (Loc loc in group) { g[loc.Row][loc.Col] = ' '; } update = true; } } } if (update) { // Console.WriteLine("delete"); // Display(g); Pack(g); Display(g); } } } static void Main() { string[] g = { " GYRR", "RYYGYG", "GYGYRR", "RYGYRG", "YGYRYG", "GYRYRG", "YGYRYR", "YGYRYR", "YRRGRG", "RYGYGG", "GRYGYR", "GRYGYR", "GRYGYR", }; char[][] gg = new char[g.Length][]; for (int i = 0; i < g.Length; i++) { gg[i] = g[i].ToCharArray(); } Solve(gg); } }
- 文字を上書きするために
string
をchar[]
に変換しています。
この問題は、Qiita の以下の記事で知りました。