#include<bits/stdc++.h> using namespace std; #ifdef DEBUG auto&operator <<(auto& o, pair<auto, auto> p) {return o<<"("<<p.first<<", "<<p.second<<")";} auto operator <<(auto& o, auto x)->decltype(x.end(), o) {o<<"{"; for(auto v : x) o<<v<<", "; return o<<"}";} #define debug(X) cout<<"["#X"]"<<X<<endl; #else #define debug(X) {} #endif #define int long long int32_t main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m; cin>>n>>m; vector<vector<pair<int, char> > > graph(n+m); vector<string> board(n); for(auto& v : board) cin>>v; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { auto v = board[i][j]; graph[i].push_back({n+j, v}); } } for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { auto v = board[j][i]; graph[i+n].push_back({j, v}); } } vector<char> col(n+m, -1); vector<int> touched; function<bool(int, char)> dfs = [&](int a, char c) { if(col[a] != -1 && col[a] != c) return false; if(col[a] == c) return true; touched.push_back(a); col[a] = c; for(auto v : graph[a]) if(v.second != c) if(!dfs(v.first, v.second)) return false; return true; }; unordered_set<int> av; for(int i=0;i<n+m;i++) { if(col[i] != -1) continue; av.clear(); vector<char> all; vector<int> cnt(30, 0); for(auto v : graph[i]) av.insert(v.second), cnt[v.second - 'A']++; if(i < n) cnt[board[i][0]-'A'] = 1e9+7; else cnt[board[0][i-n]-'A'] = 1e9+7; for(auto v : av) all.push_back(v); sort(all.begin(), all.end(), [&](char a, char b){return cnt[a-'A'] > cnt[b-'A'];}); for(char a : all) { debug(i); debug(a); touched.clear(); if(dfs(i, a)) {break;} for(auto v : touched) col[v] = -1; } } vector<unordered_set<int> > toTop(n+m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) { if(board[i][j] == col[i] && board[i][j] != col[j+n]) toTop[i].insert(j+n); if(board[i][j] != col[i] && board[i][j] == col[j+n]) toTop[j+n].insert(i); } vector<unordered_set<int> > ingraph(n+m); auto toposort = [&]() { for(int i=0;i<n+m;i++) for(auto v : toTop[i]) ingraph[v].insert(i); queue<int> q; for(int i=0;i<n+m;i++) if(toTop[i].size() == 0) q.push(i); vector<int> result; while(!q.empty()) { auto a = q.front(); q.pop(); result.push_back(a); for(auto v : ingraph[a]) { toTop[v].erase(a); if(toTop[v].size() == 0) q.push(v); } } return result; }; vector<int> d = toposort(); cout<<d.size()<<"\n"; for(auto v : d) { if(v < n) cout<<"R "<<v+1<<" "<<col[v]<<"\n"; else cout<<"K "<<v-n+1<<" "<<col[v]<<"\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 | #include<bits/stdc++.h> using namespace std; #ifdef DEBUG auto&operator <<(auto& o, pair<auto, auto> p) {return o<<"("<<p.first<<", "<<p.second<<")";} auto operator <<(auto& o, auto x)->decltype(x.end(), o) {o<<"{"; for(auto v : x) o<<v<<", "; return o<<"}";} #define debug(X) cout<<"["#X"]"<<X<<endl; #else #define debug(X) {} #endif #define int long long int32_t main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m; cin>>n>>m; vector<vector<pair<int, char> > > graph(n+m); vector<string> board(n); for(auto& v : board) cin>>v; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { auto v = board[i][j]; graph[i].push_back({n+j, v}); } } for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { auto v = board[j][i]; graph[i+n].push_back({j, v}); } } vector<char> col(n+m, -1); vector<int> touched; function<bool(int, char)> dfs = [&](int a, char c) { if(col[a] != -1 && col[a] != c) return false; if(col[a] == c) return true; touched.push_back(a); col[a] = c; for(auto v : graph[a]) if(v.second != c) if(!dfs(v.first, v.second)) return false; return true; }; unordered_set<int> av; for(int i=0;i<n+m;i++) { if(col[i] != -1) continue; av.clear(); vector<char> all; vector<int> cnt(30, 0); for(auto v : graph[i]) av.insert(v.second), cnt[v.second - 'A']++; if(i < n) cnt[board[i][0]-'A'] = 1e9+7; else cnt[board[0][i-n]-'A'] = 1e9+7; for(auto v : av) all.push_back(v); sort(all.begin(), all.end(), [&](char a, char b){return cnt[a-'A'] > cnt[b-'A'];}); for(char a : all) { debug(i); debug(a); touched.clear(); if(dfs(i, a)) {break;} for(auto v : touched) col[v] = -1; } } vector<unordered_set<int> > toTop(n+m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) { if(board[i][j] == col[i] && board[i][j] != col[j+n]) toTop[i].insert(j+n); if(board[i][j] != col[i] && board[i][j] == col[j+n]) toTop[j+n].insert(i); } vector<unordered_set<int> > ingraph(n+m); auto toposort = [&]() { for(int i=0;i<n+m;i++) for(auto v : toTop[i]) ingraph[v].insert(i); queue<int> q; for(int i=0;i<n+m;i++) if(toTop[i].size() == 0) q.push(i); vector<int> result; while(!q.empty()) { auto a = q.front(); q.pop(); result.push_back(a); for(auto v : ingraph[a]) { toTop[v].erase(a); if(toTop[v].size() == 0) q.push(v); } } return result; }; vector<int> d = toposort(); cout<<d.size()<<"\n"; for(auto v : d) { if(v < n) cout<<"R "<<v+1<<" "<<col[v]<<"\n"; else cout<<"K "<<v-n+1<<" "<<col[v]<<"\n"; } } |