#include <cstdio> #include <queue> #include <unordered_map> #include <vector> const char ROW = 'R'; const char COLUMN = 'K'; const int NN = 2020; char data[NN][NN]; struct Command { char type, color; int number; }; Command mk_cmd(char type, int number, char color) { Command c = {.type = type, .color = color, .number = number}; return c; } void increment(std::unordered_map<char, int> &map, char key) { if (map.contains(key)) { map[key] += 1; } else { map[key] = 1; } } void decrease(std::unordered_map<char, int> &map, char key) { map[key] -= 1; if (map[key] == 0) { map.erase(key); } } int main() { int Rows, Columns; scanf("%d%d", &Rows, &Columns); for (int r = 0; r < Rows; ++r) { scanf("%s", data[r]); } std::vector<std::unordered_map<char, int>> row_data; std::vector<std::unordered_map<char, int>> col_data; for (int r = 0; r < Rows; ++r) { row_data.push_back(std::unordered_map<char, int>()); } for (int c = 0; c < Columns; ++c) { col_data.push_back(std::unordered_map<char, int>()); } std::queue<Command> queue; std::vector<Command> res; for (int r = 0; r < Rows; ++r) { for (int c = 0; c < Columns; ++c) { increment(row_data[r], data[r][c]); increment(col_data[c], data[r][c]); } } int idx = 0; for (auto &rd : row_data) { if (rd.size() == 1) { queue.push(mk_cmd(ROW, idx, rd.begin()->first)); rd.clear(); } ++idx; } idx = 0; for (auto &cd : col_data) { if (cd.size() == 1) { queue.push(mk_cmd(COLUMN, idx, cd.begin()->first)); cd.clear(); } ++idx; } while (!queue.empty()) { Command exec = queue.front(); queue.pop(); res.push_back(exec); if (exec.type == ROW) { int idx = 0; for (auto &cd : col_data) { if (!cd.empty()) { decrease(cd, exec.color); if (cd.size() == 1) { queue.push(mk_cmd(COLUMN, idx, cd.begin()->first)); cd.clear(); } } ++idx; } } else { int idx = 0; for (auto &rd : row_data) { if (!rd.empty()) { decrease(rd, exec.color); if (rd.size() == 1) { queue.push(mk_cmd(ROW, idx, rd.begin()->first)); rd.clear(); } } ++idx; } } } printf("%d\n", (int) res.size()); for (auto it = res.rbegin(); it != res.rend(); ++it) { printf("%c %d %c\n", it->type, it->number + 1, it->color); } return 0; }
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 | #include <cstdio> #include <queue> #include <unordered_map> #include <vector> const char ROW = 'R'; const char COLUMN = 'K'; const int NN = 2020; char data[NN][NN]; struct Command { char type, color; int number; }; Command mk_cmd(char type, int number, char color) { Command c = {.type = type, .color = color, .number = number}; return c; } void increment(std::unordered_map<char, int> &map, char key) { if (map.contains(key)) { map[key] += 1; } else { map[key] = 1; } } void decrease(std::unordered_map<char, int> &map, char key) { map[key] -= 1; if (map[key] == 0) { map.erase(key); } } int main() { int Rows, Columns; scanf("%d%d", &Rows, &Columns); for (int r = 0; r < Rows; ++r) { scanf("%s", data[r]); } std::vector<std::unordered_map<char, int>> row_data; std::vector<std::unordered_map<char, int>> col_data; for (int r = 0; r < Rows; ++r) { row_data.push_back(std::unordered_map<char, int>()); } for (int c = 0; c < Columns; ++c) { col_data.push_back(std::unordered_map<char, int>()); } std::queue<Command> queue; std::vector<Command> res; for (int r = 0; r < Rows; ++r) { for (int c = 0; c < Columns; ++c) { increment(row_data[r], data[r][c]); increment(col_data[c], data[r][c]); } } int idx = 0; for (auto &rd : row_data) { if (rd.size() == 1) { queue.push(mk_cmd(ROW, idx, rd.begin()->first)); rd.clear(); } ++idx; } idx = 0; for (auto &cd : col_data) { if (cd.size() == 1) { queue.push(mk_cmd(COLUMN, idx, cd.begin()->first)); cd.clear(); } ++idx; } while (!queue.empty()) { Command exec = queue.front(); queue.pop(); res.push_back(exec); if (exec.type == ROW) { int idx = 0; for (auto &cd : col_data) { if (!cd.empty()) { decrease(cd, exec.color); if (cd.size() == 1) { queue.push(mk_cmd(COLUMN, idx, cd.begin()->first)); cd.clear(); } } ++idx; } } else { int idx = 0; for (auto &rd : row_data) { if (!rd.empty()) { decrease(rd, exec.color); if (rd.size() == 1) { queue.push(mk_cmd(ROW, idx, rd.begin()->first)); rd.clear(); } } ++idx; } } } printf("%d\n", (int) res.size()); for (auto it = res.rbegin(); it != res.rend(); ++it) { printf("%c %d %c\n", it->type, it->number + 1, it->color); } return 0; } |