// clang-format off
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
#define FOR(i,l,r) for(auto i=(l);i<=(r);++i)
#define REP(i,n) FOR(i,0,(n)-1)
#define ssize(x) int(x.size())
template<class A,class B>auto&operator<<(ostream&o,pair<A,B>p){return o<<"("<<p.first<<", "<<p.second<<")";}
template<class T>auto operator<<(ostream&o,T x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";}
#ifdef DEBUG
#define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n'
#else
#define debug(...) {}
#endif
// clang-format on
#define BOARD(r, c) board[(r)*dim[1] + (c)]
// Global variables
const int nchars = 'Z' - 'A' + 1;
int dim[2], nrc; // [0] nrows, [1] ncols
vector<char> board;
vector<int> diff_chars; // number of different chars in given row/column
vector<array<int, nchars>> char_cnt; // count of each chars in row/column
vector<int> to_process;
vector<pair<int, char>> ans; // (row/col, char) in reverse order
int
main()
{
cin.tie(0)->sync_with_stdio(0);
cin >> dim[0] >> dim[1];
board.resize(dim[0] * dim[1]);
for (auto& ch : board) cin >> ch;
// Preprocess the data
diff_chars.resize(nrc = dim[0] + dim[1]);
char_cnt.resize(nrc);
REP (r, dim[0]) {
REP (c, dim[1]) {
int ch = BOARD(r, c) - 'A';
if (char_cnt[r][ch]++ == 0) ++diff_chars[r];
if (char_cnt[dim[0] + c][ch]++ == 0) ++diff_chars[dim[0] + c];
}
}
debug(diff_chars);
// Find rows/cols to be processed first
REP (i, nrc)
if (diff_chars[i] == 1) to_process.emplace_back(i);
debug(to_process);
// Compute the answer in a DFS manor
ans.reserve(nrc);
while (!to_process.empty()) {
int id = to_process.back();
to_process.pop_back();
bool ifrow = id < dim[0];
char ans_ch;
REP (i, dim[ifrow]) {
auto& ch = ifrow ? BOARD(id, i) : BOARD(i, id - dim[0]);
if (ch == 0) continue;
ans_ch = ch;
int oth_id = (ifrow ? dim[0] + i : i);
if (--char_cnt[id][ch - 'A'] == 0)
if (--diff_chars[id] == 1) to_process.emplace_back(id);
if (--char_cnt[oth_id][ch - 'A'] == 0)
if (--diff_chars[oth_id] == 1) to_process.emplace_back(oth_id);
ch = 0;
}
ans.emplace_back(id, ans_ch);
}
// Output
cout << ssize(ans) << "\n";
for (auto it = ans.rbegin(); it != ans.rend(); ++it)
cout << (it->first < dim[0] ? "R " : "K ")
<< (it->first < dim[0] ? it->first : it->first - dim[0]) + 1 << " "
<< it->second << "\n";
#ifdef LOCAL
system("grep VmPeak /proc/$PPID/status >&2");
#endif
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 | // clang-format off #include<bits/stdc++.h> using namespace std; using LL=long long; #define FOR(i,l,r) for(auto i=(l);i<=(r);++i) #define REP(i,n) FOR(i,0,(n)-1) #define ssize(x) int(x.size()) template<class A,class B>auto&operator<<(ostream&o,pair<A,B>p){return o<<"("<<p.first<<", "<<p.second<<")";} template<class T>auto operator<<(ostream&o,T x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";} #ifdef DEBUG #define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n' #else #define debug(...) {} #endif // clang-format on #define BOARD(r, c) board[(r)*dim[1] + (c)] // Global variables const int nchars = 'Z' - 'A' + 1; int dim[2], nrc; // [0] nrows, [1] ncols vector<char> board; vector<int> diff_chars; // number of different chars in given row/column vector<array<int, nchars>> char_cnt; // count of each chars in row/column vector<int> to_process; vector<pair<int, char>> ans; // (row/col, char) in reverse order int main() { cin.tie(0)->sync_with_stdio(0); cin >> dim[0] >> dim[1]; board.resize(dim[0] * dim[1]); for (auto& ch : board) cin >> ch; // Preprocess the data diff_chars.resize(nrc = dim[0] + dim[1]); char_cnt.resize(nrc); REP (r, dim[0]) { REP (c, dim[1]) { int ch = BOARD(r, c) - 'A'; if (char_cnt[r][ch]++ == 0) ++diff_chars[r]; if (char_cnt[dim[0] + c][ch]++ == 0) ++diff_chars[dim[0] + c]; } } debug(diff_chars); // Find rows/cols to be processed first REP (i, nrc) if (diff_chars[i] == 1) to_process.emplace_back(i); debug(to_process); // Compute the answer in a DFS manor ans.reserve(nrc); while (!to_process.empty()) { int id = to_process.back(); to_process.pop_back(); bool ifrow = id < dim[0]; char ans_ch; REP (i, dim[ifrow]) { auto& ch = ifrow ? BOARD(id, i) : BOARD(i, id - dim[0]); if (ch == 0) continue; ans_ch = ch; int oth_id = (ifrow ? dim[0] + i : i); if (--char_cnt[id][ch - 'A'] == 0) if (--diff_chars[id] == 1) to_process.emplace_back(id); if (--char_cnt[oth_id][ch - 'A'] == 0) if (--diff_chars[oth_id] == 1) to_process.emplace_back(oth_id); ch = 0; } ans.emplace_back(id, ans_ch); } // Output cout << ssize(ans) << "\n"; for (auto it = ans.rbegin(); it != ans.rend(); ++it) cout << (it->first < dim[0] ? "R " : "K ") << (it->first < dim[0] ? it->first : it->first - dim[0]) + 1 << " " << it->second << "\n"; #ifdef LOCAL system("grep VmPeak /proc/$PPID/status >&2"); #endif return 0; } |
English