CF750H New Year and Snowy Grid
这个问题是不好判断的
考虑简单点的, 到 是否连通
那么只要在最外围一圈 #
(显然一些位置不能加),判断 和 是否能通过 #
八连通即可
如果是双连通呢?只要这两点所在连通块不能通过只加一个 #
就连通
看起来很不可做的题猜测一些简单结论就很可做了
判断否就考虑加一个 #
就连通的位置,这个 #
必然是连接了两个连通块
考虑这两个连通块的类别,一是新填的两个 #
, 枚举即可
二是连接了原图中的两个连通块,这两个连通块又通过新的 #
连通了 或
于是把所有这样的连通块记录下来,判断两两是否在原图中只加一个 #
就连通
三是一个新 #
和原图中的连通块,发现处理可以和二一样
判断两连通块是否只加一个 #
就连通可以用哈希表预处理
一次询问是临时的,可撤销并查集即可
#include <bits/stdc++.h> #define IN inline #define eb emplace_back using namespace std; int n, m, q, id[1005][1005]; char str[1005], mp[1005][1005]; const int N = 1e6 + 5e3; struct DSU { int fa[N], sz[N], top; struct Edge{int u, v;}stk[N]; IN int find(int x){while (fa[x] != x) x = fa[x]; return x;} IN void merge(int x, int y) { int u = find(x), v = find(y); if (u == v) return; if (sz[u] > sz[v]) swap(u, v); fa[u] = v, sz[v] += sz[u], stk[++top] = Edge{u, v}; } IN void clear(int lst) { for(int u, v; top != lst; --top) u = stk[top].u, v = stk[top].v, sz[v] -= sz[u], fa[u] = u; } }T1, T2; int fx[9][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}}; unordered_map<int, int> hs[N]; void dfs(int x, int y, int d, int p) { if ((x == 2 && y == 2) || (x == n - 1 && y == m - 1)) return; if (mp[x][y] == '#') hs[p][T1.find(id[x][y])] = 1; if (!d) return; for(int k = 0; k < 8; k++) { int xx = x + fx[k][0], yy = y + fx[k][1]; if (id[xx][yy]) dfs(xx, yy, d - 1, p); } } void Init() { scanf("%d%d%d", &n, &m, &q), n += 2, m += 2; for(int i = 2; i < n; i++) scanf("%s", mp[i] + 2); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) id[i][j] = (i - 1) * m + j; for(int j = 1; j <= m; j++) mp[1][j] = mp[n][j] = '#'; for(int i = 1; i <= n; i++) mp[i][1] = mp[i][m] = '#'; mp[1][1] = mp[1][2] = mp[2][1] = mp[n - 1][m] = mp[n][m - 1] = mp[n][m] = '.'; for(int i = 1; i <= n * m; i++) T1.fa[i] = i, T1.sz[i] = 1; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) if (mp[i][j] == '#') for(int k = 0; k < 8; k++) { int x = i + fx[k][0], y = j + fx[k][1]; if (id[x][y] && mp[x][y] == '#') T1.merge(id[i][j], id[x][y]); } for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) dfs(i, j, 2, T1.find(id[i][j])); for(int i = 1; i <= n * m; i++) T2.fa[i] = T1.fa[i], T2.sz[i] = T1.sz[i]; } int X[15], Y[15]; int main() { Init(); for(; q; --q) { int K; scanf("%d", &K); for(int i = 1; i <= K; i++) scanf("%d%d", &X[i], &Y[i]), mp[++X[i]][++Y[i]] = '#'; int lst = T2.top; for(int i = 1; i <= K; i++) for(int k = 0; k < 8; k++) { int x = X[i] + fx[k][0], y = Y[i] + fx[k][1]; if (id[x][y] && mp[x][y] == '#') T2.merge(id[X[i]][Y[i]], id[x][y]); } int flag = 0; for(int i = 1; i <= K && !flag; i++) for(int j = 1; j <= K; j++) if (max(abs(X[i] - X[j]), abs(Y[i] - Y[j])) <= 2) { if (T2.find(id[X[i]][Y[i]]) == T2.find(id[1][m]) && T2.find(id[X[j]][Y[j]]) == T2.find(id[n][1])) { flag = 1; break; } } vector<int> Vr, Vl; Vr.eb(T1.find(id[1][m])), Vl.eb(T1.find(id[n][1])); for(int i = 1; i <= K; i++) { for(int k = 0; k <= 8; k++) { int x = X[i] + fx[k][0], y = Y[i] + fx[k][1]; if (id[x][y] && T2.find(id[x][y]) == T2.find(id[1][m])) Vr.eb(T1.find(id[x][y])); if (id[x][y] && T2.find(id[x][y]) == T2.find(id[n][1])) Vl.eb(T1.find(id[x][y])); } } for(auto kr : Vr) for(auto kl : Vl) if (hs[kr].find(kl) != hs[kr].end() || hs[kl].find(kr) != hs[kl].end()){flag = 1; break;} if (!flag) puts("YES"); else puts("NO"); fflush(stdout); T2.clear(lst); for(int i = 1; i <= K; i++) mp[X[i]][Y[i]] = '.'; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
2022-02-22 CF1638E Colorful Operations
2020-02-22 Vladik and fractions
2020-02-22 しろは的军训列队
2020-02-22 东方CannonBall
2020-02-22 勇者sky遇上的命中注定的恋人白羽竟然是妹妹2