专栏文章
题解:AT_abc425_d [ABC425D] Ulam-Warburton Automaton
AT_abc425_d题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minr1piw
- 此快照首次捕获于
- 2025/12/02 06:57 3 个月前
- 此快照最后确认于
- 2025/12/02 06:57 3 个月前
很好的推理,令我的大脑旋转。
我们可以这么想,假定我们现在到了第 时刻,且在 到 时刻的所有其他可被染色的格子都已经染色,那么自然可以发现,第 时刻染色的格子必然与第 时刻染色的格子相邻,否则这个格子在第 时刻前就可以被染色,与我们的假定矛盾了。
那么就很好做了,我们一直记录上一次染色了那些格子,然后对这些格子的相邻格子进行判断并染色即可,这个操作可以使用滚动维护,省空间。
CPP
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e5 + 10;
vector <char> vec[N];
int h, w;
int ans;
typedef pair <int, int> pii;
vector <pii> npos[2];
int pre, now;
int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};
bool check(int x, int y) {
if(x < 1 || y < 1 || x > h || y > w) return 0;
int cnt = 0;
for (int i = 0; i < 4; i ++) {
int tox = x + dx[i], toy = y + dy[i];
if(tox < 1 || toy < 1 || tox > h || toy > w) continue ;
cnt += vec[tox][toy] == '#';
}
return cnt == 1;
}
signed main(void) {
cin >> h >> w;
pre = 0, now = 1;
for (int i = 1; i <= h; i ++) {
vec[i].emplace_back('*');
for (int j = 1; j <= w; j ++) {
char k;
cin >> k;
vec[i].emplace_back(k);
if(k == '#') npos[pre].emplace_back(make_pair(i, j)), ans ++;
}
vec[i].emplace_back('*');
}
while (npos[pre].size()) {
npos[now].clear();
for (auto [u, v] : npos[pre]) {
for (int i = 0; i < 4; i ++) {
int tox = u + dx[i], toy = v + dy[i];
if(check(tox, toy) && vec[tox][toy] != '#') {
ans ++;
npos[now].emplace_back(make_pair(tox, toy));
}
}
}
for (auto [u, v] : npos[now]) vec[u][v] = '#';
swap(pre, now);
}
cout << ans << endl;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...