【每日一题】5月12日模拟战役
模拟战役
https://ac.nowcoder.com/acm/problem/14698
解题思路
终于有一个简单模拟了。
虽然这题介绍一大堆,总结起来就是几句话,给出地图n列,前4行是a的地盘,后四行是b的地盘,每个人地盘上面有星号代表大炮。
大炮会 3 * 3的波及周围,会一直传递,b先手,a立刻反击b出手的大炮,问b能不能消灭a全部的大炮,如果能最后剩余最大大炮数是几。
那么很显然,我们发现a处于究极被动方,b是无敌主动方,我们通过方便一次跑图,把攻击一个地方,波及到周边的大炮都合并到一个点去。
我们发现如果a最后的点数大于b的点数,那么b永远消灭不完a,输出-1。
否则,对于b来说,反正我都要把你a消灭干净,谁先谁后没得关系。但是出手的大炮却可以控制,把一个点上大炮数量最少的拉上去当炮灰,先死。
最后留下的一定大炮总数就是最大的了。
#include <bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } const int N = 105; int a[N], b[N]; int n, cnta, cntb; char mp[10][N]; int num; void dfs(int x, int y, int ed) { //ed规定地图上方边界 if (mp[x][y] == '.') return; mp[x][y] = '.', ++num; for (int i = -1; i <= 1; ++i) for (int j = -1; j <= 1; ++j) if (!i && !j) continue; else { int dx = x + i, dy = y + j; if (dx >= ed && dx < 4 + ed && dy >= 0 && dy < n) dfs(dx, dy, ed); } } int main() { n = read(); for (int i = 0; i < 8; ++i) scanf("%s", mp + i); for (int i = 0; i < 4; ++i) for (int j = 0; j < n; ++j) if (mp[i][j] == '*') { num = 0; dfs(i, j, 0); a[++cnta] = num; } for (int i = 4; i < 8; ++i) for (int j = 0; j < n; ++j) if (mp[i][j] == '*') { num = 0; dfs(i, j, 4); b[++cntb] = num; } if (cnta > cntb) puts("-1"); else { sort(b + 1, b + 1 + cntb); int ans = 0; for (int i = cnta; i <= cntb; ++i) ans += b[i]; printf("%d\n", ans); } return 0; }
每日一题 文章被收录于专栏
每日一题