// // Created by piotr on 14.03.2024. // #include <algorithm> #include <array> #include <cstdio> #include <cassert> #include <list> #include <stack> #include <vector> using kolor = unsigned char; const kolor NC = 'Z' - 'A' + 1; enum Typ { RZAD='R', KOLUMNA='K' }; class Szereg { const kolor NOC = 255; std::array<int, NC> kolory; int suma = 0; kolor maks_kolor = 0; public: const Typ typ; const int indeks; public: Szereg(Typ typ, int indeks) : typ(typ), indeks(indeks) { kolory.fill(0); } kolor get_maks_kolor(void) { if (maks_kolor == NOC) { maks_kolor = std::max_element(kolory.begin(), kolory.end()) - kolory.begin(); } return maks_kolor; } bool is_single_kolor(void) { return kolory[get_maks_kolor()] == suma; } void dodaj_kolor(kolor c, int zmiana) { kolory[c] += zmiana; suma += zmiana; maks_kolor = NOC; } }; struct Instrukcja { Typ t; int i; kolor c; }; kolor X[2000][2000]; int main() { int NR, NK; assert(scanf("%d%d", &NR, &NK) == 2); std::vector<Szereg> rzedy, kolumny; rzedy.reserve(NR); kolumny.reserve(NK); for (int r=0; r<NR; ++r) { rzedy.emplace_back(RZAD, r); } for (int k=0; k<NK; ++k) { kolumny.emplace_back(KOLUMNA, k); } for (int r=0; r<NR; ++r) { assert(getchar() == '\n'); for (int k=0; k<NK; ++k) { kolor c = getchar() - 'A'; X[r][k] = c; rzedy[r].dodaj_kolor(c, +1); kolumny[k].dodaj_kolor(c, +1); } } std::list<Szereg> szeregi; for (int r=0; r<NR; ++r) { szeregi.push_back(rzedy[r]); } for (int k=0; k<NK; ++k) { szeregi.push_back(kolumny[k]); } std::stack<Instrukcja> instrukcje; int R = NR, K = NK; while (R>0 && K>0 && !szeregi.empty()) { auto it0 = std::find_if(szeregi.begin(), szeregi.end(), [](Szereg& s){ return s.is_single_kolor(); }); assert(it0 != szeregi.end()); Szereg wybrany = *it0; szeregi.erase(it0); if (wybrany.typ == RZAD) --R; else --K; const kolor c = wybrany.get_maks_kolor(); instrukcje.push({wybrany.typ, wybrany.indeks, c}); for (Szereg& inny : szeregi) { if (inny.typ != wybrany.typ) { inny.dodaj_kolor(c, -1); } } } printf("%lu\n", instrukcje.size()); while (!instrukcje.empty()) { const Instrukcja& i = instrukcje.top(); printf("%c %d %c\n", i.t, i.i+1, i.c+'A'); instrukcje.pop(); } }
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 | // // Created by piotr on 14.03.2024. // #include <algorithm> #include <array> #include <cstdio> #include <cassert> #include <list> #include <stack> #include <vector> using kolor = unsigned char; const kolor NC = 'Z' - 'A' + 1; enum Typ { RZAD='R', KOLUMNA='K' }; class Szereg { const kolor NOC = 255; std::array<int, NC> kolory; int suma = 0; kolor maks_kolor = 0; public: const Typ typ; const int indeks; public: Szereg(Typ typ, int indeks) : typ(typ), indeks(indeks) { kolory.fill(0); } kolor get_maks_kolor(void) { if (maks_kolor == NOC) { maks_kolor = std::max_element(kolory.begin(), kolory.end()) - kolory.begin(); } return maks_kolor; } bool is_single_kolor(void) { return kolory[get_maks_kolor()] == suma; } void dodaj_kolor(kolor c, int zmiana) { kolory[c] += zmiana; suma += zmiana; maks_kolor = NOC; } }; struct Instrukcja { Typ t; int i; kolor c; }; kolor X[2000][2000]; int main() { int NR, NK; assert(scanf("%d%d", &NR, &NK) == 2); std::vector<Szereg> rzedy, kolumny; rzedy.reserve(NR); kolumny.reserve(NK); for (int r=0; r<NR; ++r) { rzedy.emplace_back(RZAD, r); } for (int k=0; k<NK; ++k) { kolumny.emplace_back(KOLUMNA, k); } for (int r=0; r<NR; ++r) { assert(getchar() == '\n'); for (int k=0; k<NK; ++k) { kolor c = getchar() - 'A'; X[r][k] = c; rzedy[r].dodaj_kolor(c, +1); kolumny[k].dodaj_kolor(c, +1); } } std::list<Szereg> szeregi; for (int r=0; r<NR; ++r) { szeregi.push_back(rzedy[r]); } for (int k=0; k<NK; ++k) { szeregi.push_back(kolumny[k]); } std::stack<Instrukcja> instrukcje; int R = NR, K = NK; while (R>0 && K>0 && !szeregi.empty()) { auto it0 = std::find_if(szeregi.begin(), szeregi.end(), [](Szereg& s){ return s.is_single_kolor(); }); assert(it0 != szeregi.end()); Szereg wybrany = *it0; szeregi.erase(it0); if (wybrany.typ == RZAD) --R; else --K; const kolor c = wybrany.get_maks_kolor(); instrukcje.push({wybrany.typ, wybrany.indeks, c}); for (Szereg& inny : szeregi) { if (inny.typ != wybrany.typ) { inny.dodaj_kolor(c, -1); } } } printf("%lu\n", instrukcje.size()); while (!instrukcje.empty()) { const Instrukcja& i = instrukcje.top(); printf("%c %d %c\n", i.t, i.i+1, i.c+'A'); instrukcje.pop(); } } |