#include <bits/stdc++.h> using namespace std; const int N = 2000 + 7; int n, m; char board[N][N]; map<char, int> row[N], col[N]; vector<tuple<char, int, char>> ans; bool done_row[N], done_col[N]; int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%s", board[i] + 1); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { row[i][board[i][j]]++; col[j][board[i][j]]++; } } queue<int> P, Q; for (int i = 1; i <= n; i++) if (row[i].size() <= 1) { P.push(i); done_row[i] = true; } for (int j = 1; j <= m; j++) if (col[j].size() <= 1) { Q.push(j); done_col[j] = true; } while (P.size() || Q.size()) { /* for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cerr << board[i][j] << ' '; } cerr << '\n'; } cerr << '\n'; */ if (P.size()) { int r = P.front(); P.pop(); assert(row[r].size() <= 1); char ch = 'X'; if (row[r].size()) ch = row[r].begin()->first; ans.emplace_back('R', r, ch); for (int j = 1; j <= m; j++) { if (board[r][j] != '?') { if (--col[j][board[r][j]] == 0) { col[j].erase(board[r][j]); if (col[j].size() <= 1 && done_col[j] == false) { done_col[j] = true; Q.push(j); } } board[r][j] = '?'; } } } else { int c = Q.front(); Q.pop(); assert(col[c].size() <= 1); char ch = 'Y'; if (col[c].size()) ch = col[c].begin()->first; ans.emplace_back('K', c, ch); for (int i = 1; i <= n; i++) { if (board[i][c] != '?') { if (--row[i][board[i][c]] == 0) { row[i].erase(board[i][c]); if (row[i].size() <= 1 && done_row[i] == false) { done_row[i] = true; P.push(i); } } board[i][c] = '?'; } } } } reverse(ans.begin(), ans.end()); assert((int) ans.size() <= n + m); cout << ans.size() << '\n'; for (auto&& [op, idx, color] : ans) cout << op << ' ' << idx << ' ' << color << '\n'; }
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 | #include <bits/stdc++.h> using namespace std; const int N = 2000 + 7; int n, m; char board[N][N]; map<char, int> row[N], col[N]; vector<tuple<char, int, char>> ans; bool done_row[N], done_col[N]; int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%s", board[i] + 1); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { row[i][board[i][j]]++; col[j][board[i][j]]++; } } queue<int> P, Q; for (int i = 1; i <= n; i++) if (row[i].size() <= 1) { P.push(i); done_row[i] = true; } for (int j = 1; j <= m; j++) if (col[j].size() <= 1) { Q.push(j); done_col[j] = true; } while (P.size() || Q.size()) { /* for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cerr << board[i][j] << ' '; } cerr << '\n'; } cerr << '\n'; */ if (P.size()) { int r = P.front(); P.pop(); assert(row[r].size() <= 1); char ch = 'X'; if (row[r].size()) ch = row[r].begin()->first; ans.emplace_back('R', r, ch); for (int j = 1; j <= m; j++) { if (board[r][j] != '?') { if (--col[j][board[r][j]] == 0) { col[j].erase(board[r][j]); if (col[j].size() <= 1 && done_col[j] == false) { done_col[j] = true; Q.push(j); } } board[r][j] = '?'; } } } else { int c = Q.front(); Q.pop(); assert(col[c].size() <= 1); char ch = 'Y'; if (col[c].size()) ch = col[c].begin()->first; ans.emplace_back('K', c, ch); for (int i = 1; i <= n; i++) { if (board[i][c] != '?') { if (--row[i][board[i][c]] == 0) { row[i].erase(board[i][c]); if (row[i].size() <= 1 && done_row[i] == false) { done_row[i] = true; P.push(i); } } board[i][c] = '?'; } } } } reverse(ans.begin(), ans.end()); assert((int) ans.size() <= n + m); cout << ans.size() << '\n'; for (auto&& [op, idx, color] : ans) cout << op << ' ' << idx << ' ' << color << '\n'; } |