#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <bitset>
#include <random>
#pragma GCC optimize("Os")
using ll = long long;
#define debug(x) #x << " = " << x << '\n'
const int NMAX = 3000;
char a[NMAX][NMAX];
int vertical[NMAX][NMAX], horizontal[NMAX][NMAX];
std::bitset<NMAX * NMAX / 3> vis;
int l[NMAX * NMAX / 3], r[NMAX * NMAX / 3];
std::vector<std::pair<int, int>> edges;
bool cupleaza(int u) {
vis[u] = true;
int st = std::lower_bound(edges.begin(), edges.end(), std::pair<int, int>{u, 0}) - edges.begin();
int dr = std::lower_bound(edges.begin(), edges.end(), std::pair<int, int>{u + 1, 0}) - edges.begin() - 1;
for (int idv = st; idv <= dr; idv++) {
int v = edges[idv].second;
if (r[v] == -1) {
r[v] = u;
l[u] = v;
return true;
}
}
for (int idv = st; idv <= dr; idv++) {
int v = edges[idv].second;
if (!vis[r[v]] && cupleaza(r[v])) {
l[u] = v;
r[v] = u;
return true;
}
}
return false;
}
std::mt19937 rng(123);
int cntL, cntR;
int vertl[NMAX * NMAX / 3], vertr[NMAX * NMAX / 3];
int main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
int n, m;
std::cin >> n >> m;
for (int i = 0; i < n; i++) {
std::string s;
std::cin >> s;
for (int j = 0; j < m; j++) {
a[i][j] = s[j];
}
}
int answer = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
vertical[i][j] = horizontal[i][j] = -1;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j + 2 < m; j++) {
if (a[i][j] == 'R' && a[i][j + 1] == 'G' && a[i][j + 2] == 'W') {
vertl[cntL++] = i * m + j;
vertical[i][j] = vertical[i][j + 1] = vertical[i][j + 2] = i * m + j;
}
}
}
for (int i = 0; i + 2 < n; i++) {
for (int j = 0; j < m; j++) {
if (a[i][j] == 'R' && a[i + 1][j] == 'G' && a[i + 2][j] == 'W') {
vertr[cntR++] = i * m + j;
horizontal[i][j] = horizontal[i + 1][j] = horizontal[i + 2][j] = i * m + j;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (vertical[i][j] != -1 && horizontal[i][j] != -1) {
int x = std::lower_bound(vertl, vertl + cntL, vertical[i][j]) - vertl;
int y = std::lower_bound(vertr, vertr + cntR, horizontal[i][j]) - vertr;
edges.push_back({x, y});
}
}
}
edges.push_back({-1, -1});
edges.push_back({1e9, 1e9});
std::sort(edges.begin(), edges.end());
edges.erase(std::unique(edges.begin(), edges.end()), edges.end());
int sz = (int) edges.size();
for (int i = 0; i < sz; i++) {
edges.push_back({edges[i].second, edges[i].first});
}
std::sort(edges.begin(), edges.end());
edges.erase(std::unique(edges.begin(), edges.end()), edges.end());
bool repeat = true;
for (int i = 0; i < cntL; i++) {
l[i] = -1;
}
for (int i = 0; i < cntR; i++) {
r[i] = -1;
}
while (repeat) {
repeat = false;
for (int i = 0; i < cntL; i++) {
vis[i] = false;
}
for (int i = 0; i < cntL; i++) {
if (l[i] == -1 && cupleaza(i)) {
answer++;
repeat = true;
}
}
}
answer = cntL + cntR - answer;
std::cout << answer;
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |