// #include <bits/stdc++.h> #define FAST ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0); #include <iostream> #include <vector> #include <unordered_map> #include <unordered_set> #include <stack> using namespace std; struct color_move { char side; int no; char color; }; struct orientation_summary{ char orientation; int n; int m; vector<unordered_map<char, int>> color_count; unordered_map<char,int> already_colored; int alread_colored_total; unordered_set<int> to_color; orientation_summary(char orientation, int n, int m) { this->orientation = orientation; this->n = n; this->m = m; this->alread_colored_total = 0; this->to_color.reserve(n); this->color_count = vector<unordered_map<char, int>>(n); for (int i = 0; i < n; i++) { this->to_color.insert(i); } }; char *next_color(int n) { for (auto a: color_count[n]) { if (this->alread_colored_total+a.second - this->already_colored[a.first] == this->m) { char *x = new(char); *x = a.first; return x; } } return NULL; }; void other_colored(char t) { already_colored[t] ++; alread_colored_total++; }; }; int main() { FAST int n,m; cin >> n >> m; char x; orientation_summary row = orientation_summary('R', n,m); orientation_summary col = orientation_summary('K', m,n); stack<color_move> q; for (int i = 0; i < n; i++) { for (int j = 0 ; j< m ; j++) { cin >>x; row.color_count[i][x]++; col.color_count[j][x]++; } } char *tmp; int tmpn; stack<int> done; while (row.to_color.size() && col.to_color.size()) { for (auto x: row.to_color) { tmp = row.next_color(x); if(tmp == NULL) { continue; } col.other_colored(*tmp); done.push(x); q.push(color_move{ side: row.orientation, no: x, color: *tmp, }); } while (done.size()) { tmpn = done.top(); done.pop(); row.to_color.erase(tmpn); } if (!row.to_color.size()) { break; } for (auto x: col.to_color) { tmp = col.next_color(x); if(tmp == NULL) { continue; } row.other_colored(*tmp); done.push(x); q.push(color_move{ side: col.orientation, no: x, color: *tmp, }); } while (done.size()) { tmpn = done.top(); done.pop(); col.to_color.erase(tmpn); } } color_move next; cout << q.size()<< "\n"; while (q.size()) { next = q.top(); q.pop(); cout << next.side << " " << next.no +1 << " " << next.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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | // #include <bits/stdc++.h> #define FAST ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0); #include <iostream> #include <vector> #include <unordered_map> #include <unordered_set> #include <stack> using namespace std; struct color_move { char side; int no; char color; }; struct orientation_summary{ char orientation; int n; int m; vector<unordered_map<char, int>> color_count; unordered_map<char,int> already_colored; int alread_colored_total; unordered_set<int> to_color; orientation_summary(char orientation, int n, int m) { this->orientation = orientation; this->n = n; this->m = m; this->alread_colored_total = 0; this->to_color.reserve(n); this->color_count = vector<unordered_map<char, int>>(n); for (int i = 0; i < n; i++) { this->to_color.insert(i); } }; char *next_color(int n) { for (auto a: color_count[n]) { if (this->alread_colored_total+a.second - this->already_colored[a.first] == this->m) { char *x = new(char); *x = a.first; return x; } } return NULL; }; void other_colored(char t) { already_colored[t] ++; alread_colored_total++; }; }; int main() { FAST int n,m; cin >> n >> m; char x; orientation_summary row = orientation_summary('R', n,m); orientation_summary col = orientation_summary('K', m,n); stack<color_move> q; for (int i = 0; i < n; i++) { for (int j = 0 ; j< m ; j++) { cin >>x; row.color_count[i][x]++; col.color_count[j][x]++; } } char *tmp; int tmpn; stack<int> done; while (row.to_color.size() && col.to_color.size()) { for (auto x: row.to_color) { tmp = row.next_color(x); if(tmp == NULL) { continue; } col.other_colored(*tmp); done.push(x); q.push(color_move{ side: row.orientation, no: x, color: *tmp, }); } while (done.size()) { tmpn = done.top(); done.pop(); row.to_color.erase(tmpn); } if (!row.to_color.size()) { break; } for (auto x: col.to_color) { tmp = col.next_color(x); if(tmp == NULL) { continue; } row.other_colored(*tmp); done.push(x); q.push(color_move{ side: col.orientation, no: x, color: *tmp, }); } while (done.size()) { tmpn = done.top(); done.pop(); col.to_color.erase(tmpn); } } color_move next; cout << q.size()<< "\n"; while (q.size()) { next = q.top(); q.pop(); cout << next.side << " " << next.no +1 << " " << next.color << "\n"; } } |