2023年12月算法精英 开心消消乐 题型:大模拟 搜索

59 阅读1分钟

赛氪OJ-专注于算法竞赛的在线评测系统 (saikr.com) image.png

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;
}

image.png