#include <algorithm> #include <iostream> #include <map> #include <queue> #include <vector> using namespace std; struct TestCase { int n, m; vector<vector<char>> board; }; TestCase read_test_case() { TestCase tc; cin >> tc.n >> tc.m; tc.board.resize(tc.n); for (auto& row : tc.board) { row.resize(tc.m); for (auto& c : row) cin >> c; } return tc; } void solve_test_case(TestCase tc); int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); solve_test_case(read_test_case()); } enum class Direction { Row, Column }; struct Action { Direction direction; int number; char c; }; template <typename T, typename U> T get_first_key(const map<T, U>& m) { for (const auto& [k, v] : m) return k; throw "map is empty"; } void solve_test_case(TestCase tc) { vector<map<char, int>> colors_in_row(tc.n); vector<map<char, int>> colors_in_column(tc.m); for (int i = 0; i < tc.n; i++) for (int j = 0; j < tc.m; j++) { char c = tc.board[i][j]; colors_in_row[i][c]++; colors_in_column[j][c]++; } vector<Action> result; queue<Action> q; for (int i = 0; i < tc.n; i++) { if (colors_in_row[i].size() == 1) q.push({Direction::Row, i, get_first_key(colors_in_row[i])}); } for (int j = 0; j < tc.m; j++) { if (colors_in_column[j].size() == 1) q.push({Direction::Column, j, get_first_key(colors_in_column[j])}); } while (!q.empty()) { Action a = q.front(); q.pop(); if (a.direction == Direction::Row) { if (colors_in_row[a.number].empty()) continue; colors_in_row[a.number].clear(); for (int j = 0; j < tc.m; j++) { if (colors_in_column[j][a.c] == 0) continue; colors_in_column[j][a.c]--; if (colors_in_column[j][a.c] == 0) colors_in_column[j].erase(a.c); if (colors_in_column[j].size() == 1) q.push({Direction::Column, j, get_first_key(colors_in_column[j])}); } } else if (a.direction == Direction::Column) { if (colors_in_column[a.number].empty()) continue; colors_in_column[a.number].clear(); for (int i = 0; i < tc.n; i++) { if (colors_in_row[i][a.c] == 0) continue; colors_in_row[i][a.c]--; if (colors_in_row[i][a.c] == 0) colors_in_row[i].erase(a.c); if (colors_in_row[i].size() == 1) q.push({Direction::Row, i, get_first_key(colors_in_row[i])}); } } result.push_back(a); } reverse(result.begin(), result.end()); cout << result.size() << "\n"; for (auto a : result) { switch (a.direction) { case Direction::Row: cout << "R " << a.number + 1 << " " << a.c << "\n"; break; case Direction::Column: cout << "K " << a.number + 1 << " " << a.c << "\n"; break; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include <algorithm> #include <iostream> #include <map> #include <queue> #include <vector> using namespace std; struct TestCase { int n, m; vector<vector<char>> board; }; TestCase read_test_case() { TestCase tc; cin >> tc.n >> tc.m; tc.board.resize(tc.n); for (auto& row : tc.board) { row.resize(tc.m); for (auto& c : row) cin >> c; } return tc; } void solve_test_case(TestCase tc); int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); solve_test_case(read_test_case()); } enum class Direction { Row, Column }; struct Action { Direction direction; int number; char c; }; template <typename T, typename U> T get_first_key(const map<T, U>& m) { for (const auto& [k, v] : m) return k; throw "map is empty"; } void solve_test_case(TestCase tc) { vector<map<char, int>> colors_in_row(tc.n); vector<map<char, int>> colors_in_column(tc.m); for (int i = 0; i < tc.n; i++) for (int j = 0; j < tc.m; j++) { char c = tc.board[i][j]; colors_in_row[i][c]++; colors_in_column[j][c]++; } vector<Action> result; queue<Action> q; for (int i = 0; i < tc.n; i++) { if (colors_in_row[i].size() == 1) q.push({Direction::Row, i, get_first_key(colors_in_row[i])}); } for (int j = 0; j < tc.m; j++) { if (colors_in_column[j].size() == 1) q.push({Direction::Column, j, get_first_key(colors_in_column[j])}); } while (!q.empty()) { Action a = q.front(); q.pop(); if (a.direction == Direction::Row) { if (colors_in_row[a.number].empty()) continue; colors_in_row[a.number].clear(); for (int j = 0; j < tc.m; j++) { if (colors_in_column[j][a.c] == 0) continue; colors_in_column[j][a.c]--; if (colors_in_column[j][a.c] == 0) colors_in_column[j].erase(a.c); if (colors_in_column[j].size() == 1) q.push({Direction::Column, j, get_first_key(colors_in_column[j])}); } } else if (a.direction == Direction::Column) { if (colors_in_column[a.number].empty()) continue; colors_in_column[a.number].clear(); for (int i = 0; i < tc.n; i++) { if (colors_in_row[i][a.c] == 0) continue; colors_in_row[i][a.c]--; if (colors_in_row[i][a.c] == 0) colors_in_row[i].erase(a.c); if (colors_in_row[i].size() == 1) q.push({Direction::Row, i, get_first_key(colors_in_row[i])}); } } result.push_back(a); } reverse(result.begin(), result.end()); cout << result.size() << "\n"; for (auto a : result) { switch (a.direction) { case Direction::Row: cout << "R " << a.number + 1 << " " << a.c << "\n"; break; case Direction::Column: cout << "K " << a.number + 1 << " " << a.c << "\n"; break; } } } |