赛氪OJ-专注于算法竞赛的在线评测系统 (saikr.com)
code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pp pair<pair<int,int>,int>
const int N = 2e7 + 10;
const int M = 27;
const int mo = 1e9 + 7;
int n, m, x, y, z, manx, sum;
int p[20][20];
int g[20][20];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
void dfs() {
manx = max(manx, sum);
stack<pp> q;
for (int i = n; i >= 1; i--) {
for (int j = 1; j <= m; j++) {
p[i][j] = 0;
//如果当前不是最后一行 并且 下一行被消掉了
if (i != n && g[i + 1][j] == 0) {
x = i; //从当前行开始
//如果没有越界 并且 下一行被消掉了
while (x + 1 <= n && g[x + 1][j] == 0) {
x++; //就继续向下找没有被消掉的那一行
}
g[x][j] = g[i][j]; //下沉
g[i][j] = 0; //原来的行要消掉
q.push({{x, i}, j});
}
}
}
int len = 0;
vector<vector<pair<int, int> > > v(25);
for (int i = n; i >= 1; i--) {
for (int j = 1; j <= m; j++) {
queue<pair<int, int> > qu;
if (p[i][j] == 0 && g[i][j]) {
len++;
p[i][j] = len;
qu.push({i, j});
while (!qu.empty()) {
auto[x, y] = qu.front();
v[len].push_back({x, y});
qu.pop();
for (int k = 0; k < 4; k++) {
int tx = dx[k] + x;
int ty = dy[k] + y;
if (p[tx][ty] || g[tx][ty] != g[i][j]) {
continue;
}
p[tx][ty] = len;
qu.push({tx, ty});
}
}
}
}
}
for (int i = 1; i <= len; i++) {
if (v[i].size() >= 3) {
int temp;
for (auto[x, y] : v[i]) {
temp = g[x][y];
g[x][y] = 0;
sum++;
}
dfs();
for (auto[x, y] : v[i]) {
sum--;
g[x][y] = temp;
}
}
}
while (!q.empty()) {
auto[tx, y] = q.top();
g[tx.second][y] = g[tx.first][y];
q.pop();
}
}
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> g[i][j];
dfs();
cout << manx;
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
int t = 1;
while (t--) {
solve();
}
return 0;
}