#include <bits/stdc++.h> using std::cin, std::cout, std::vector; void init_io() { cin.tie(nullptr); std::ios::sync_with_stdio(false); } constexpr unsigned num_dirs = 2; constexpr unsigned alphabet = 26; const char dir_names[num_dirs] = {'R', 'K'}; struct Line { unsigned num_colors = 0; unsigned xor_colors = 0; unsigned counts[26] = {}; void add(const unsigned color) { if (counts[color]==0) { num_colors += 1; xor_colors ^= color; } ++counts[color]; } bool remove(const unsigned color) { assert(counts[color] != 0); counts[color] -= 1; if (counts[color] == 0) { num_colors -= 1; xor_colors ^= color; return num_colors == 1; } return false; } }; struct Move { unsigned dir; unsigned x; unsigned color; }; struct LineIndex { unsigned dir; unsigned x; }; class Board { public: void read() { unsigned size[2]; for (unsigned dir=0; dir<num_dirs; ++dir) { cin >> size[dir]; lines[dir].resize(size[dir]); } for (unsigned x0=0; x0<size[0]; ++x0) { for (unsigned x1=0; x1<size[1]; ++x1) { char c; cin >> c; const unsigned color = c - 'A'; lines[0][x0].add(color); lines[1][x1].add(color); } } } vector<Move> solve() { vector<LineIndex> ready; for (unsigned dir=0; dir<num_dirs; ++dir) { for (unsigned x=0; x<lines[dir].size(); ++x) { if (lines[dir][x].num_colors <= 1) { ready.push_back(LineIndex{dir, x}); } } } vector<Move> moves; for (unsigned iter=0; iter < lines[0].size() + lines[1].size(); ++iter) { assert(!ready.empty()); const LineIndex li = ready.back(); ready.pop_back(); Line &line = lines[li.dir][li.x]; if (line.num_colors == 0) continue; assert(line.num_colors == 1); const unsigned color = line.xor_colors; moves.push_back(Move{li.dir, li.x, color}); line.num_colors = 0; line.xor_colors = 0; line.counts[color] = 0; const unsigned dir2 = li.dir ^ 1u; for (unsigned y=0; y < lines[dir2].size(); ++y) { Line &line2 = lines[dir2][y]; if (line2.num_colors != 0 && line2.remove(color)) { ready.push_back(LineIndex{dir2, y}); } } } std::reverse(moves.begin(), moves.end()); return moves; } private: vector<Line> lines[num_dirs]; }; void print(const vector<Move> &moves) { cout << moves.size() << "\n"; for (const Move &move : moves) { cout << dir_names[move.dir] << " " << (move.x + 1) << " " << char('A' + move.color) << "\n"; } } int main() { init_io(); Board board; board.read(); const auto result = board.solve(); print(result); }
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 120 121 122 123 124 125 126 | #include <bits/stdc++.h> using std::cin, std::cout, std::vector; void init_io() { cin.tie(nullptr); std::ios::sync_with_stdio(false); } constexpr unsigned num_dirs = 2; constexpr unsigned alphabet = 26; const char dir_names[num_dirs] = {'R', 'K'}; struct Line { unsigned num_colors = 0; unsigned xor_colors = 0; unsigned counts[26] = {}; void add(const unsigned color) { if (counts[color]==0) { num_colors += 1; xor_colors ^= color; } ++counts[color]; } bool remove(const unsigned color) { assert(counts[color] != 0); counts[color] -= 1; if (counts[color] == 0) { num_colors -= 1; xor_colors ^= color; return num_colors == 1; } return false; } }; struct Move { unsigned dir; unsigned x; unsigned color; }; struct LineIndex { unsigned dir; unsigned x; }; class Board { public: void read() { unsigned size[2]; for (unsigned dir=0; dir<num_dirs; ++dir) { cin >> size[dir]; lines[dir].resize(size[dir]); } for (unsigned x0=0; x0<size[0]; ++x0) { for (unsigned x1=0; x1<size[1]; ++x1) { char c; cin >> c; const unsigned color = c - 'A'; lines[0][x0].add(color); lines[1][x1].add(color); } } } vector<Move> solve() { vector<LineIndex> ready; for (unsigned dir=0; dir<num_dirs; ++dir) { for (unsigned x=0; x<lines[dir].size(); ++x) { if (lines[dir][x].num_colors <= 1) { ready.push_back(LineIndex{dir, x}); } } } vector<Move> moves; for (unsigned iter=0; iter < lines[0].size() + lines[1].size(); ++iter) { assert(!ready.empty()); const LineIndex li = ready.back(); ready.pop_back(); Line &line = lines[li.dir][li.x]; if (line.num_colors == 0) continue; assert(line.num_colors == 1); const unsigned color = line.xor_colors; moves.push_back(Move{li.dir, li.x, color}); line.num_colors = 0; line.xor_colors = 0; line.counts[color] = 0; const unsigned dir2 = li.dir ^ 1u; for (unsigned y=0; y < lines[dir2].size(); ++y) { Line &line2 = lines[dir2][y]; if (line2.num_colors != 0 && line2.remove(color)) { ready.push_back(LineIndex{dir2, y}); } } } std::reverse(moves.begin(), moves.end()); return moves; } private: vector<Line> lines[num_dirs]; }; void print(const vector<Move> &moves) { cout << moves.size() << "\n"; for (const Move &move : moves) { cout << dir_names[move.dir] << " " << (move.x + 1) << " " << char('A' + move.color) << "\n"; } } int main() { init_io(); Board board; board.read(); const auto result = board.solve(); print(result); } |