【每日一题】28. 模拟战役 (模拟 + DFS/BFS/并查集)

补题链接:Here

本题属于一道模拟题

虽然这题介绍一大堆,总结起来就是几句话,给出地图n列,前4行是a的地盘,后四行是b的地盘,每个人地盘上面有星号代表大炮。
大炮会 3 * 3的波及周围,会一直传递,b先手,a立刻反击b出手的大炮,问b能不能消灭a全部的大炮,如果能最后剩余最大大炮数是几。
那么很显然,我们发现a处于究极被动方,b是无敌主动方,我们通过方便一次跑图,把攻击一个地方,波及到周边的大炮都合并到一个点去。
我们发现如果a最后的点数大于b的点数,那么b永远消灭不完a,输出-1。
否则,对于b来说,反正我都要把你a消灭干净,谁先谁后没得关系。但是出手的大炮却可以控制,把一个点上大炮数量最少的拉上去当炮灰,先死。
最后留下的一定大炮总数就是最大的了。

const int N = 110;
string g[10];
int a[N], b[N];
int cnta, cntb, cnt;
int n;
void dfs(int x, int y, int Edge) { // Edge边界
	if (g[x][y] == '.')return ;
	g[x][y] = '.', cnt++;
	for (int i = -1; i <= 1; ++i)
		for (int j = -1; j <= 1; ++j)
			if (!i and !j)continue;
			else {
				int dx = x + i, dy = y + j;
				if (dx >= Edge and dx < 4 + Edge and dy >= 0 and dy < n)
					dfs(dx, dy, Edge);
			}
}
void solve() {
	cin >> n;
	for (int i = 0; i < 8; ++i)cin >> g[i];
	for (int i = 0; i < 4; ++i)
		for (int j = 0; j < n; ++j)
			if (g[i][j] == '*') {
				cnt = 0;
				dfs(i, j, 0);
				a[++cnta] = cnt;
			}
	for (int i = 4; i < 8; ++i)
		for (int j = 0; j < n; ++j)
			if (g[i][j] == '*') {
				cnt = 0;
				dfs(i, j, 4);
				b[++cntb] = cnt;
			}
	if (cnta > cntb) {cout << "-1\n"; return ;}
	sort(b + 1, b + 1 + cntb);
	int ans = 0;
	for (int i = cnta; i <= cntb; ++i)ans += b[i];
	cout << ans << "\n";
}
posted @   RioTian  阅读(101)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 全程不用写代码,我用AI程序员写了一个飞机大战
点击右上角即可分享
微信分享提示