随手练——P1141 01迷宫
1、暴力版
本质上就是求连通块数量,那么DFS或者BFS都行,暴力跑。
写完发现题目比较特殊,m次提问,那每次都暴力搜,肯定是要跑死了。
#include <iostream> #include <string.h> #include <stdio.h> int cnt,n; int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} }; bool fuck[1005][1005]; char s[1005][1005]; void dfs(int x, int y) { for (int k = 0; k < 4; k++) { int tox = x + dir[k][0], toy = y + dir[k][1]; if (!fuck[tox][toy] && s[x][y] != s[tox][toy] && (tox >= 0 && tox < n && toy >= 0 && toy < n)) { cnt++; fuck[tox][toy] = true; dfs(tox, toy); } } } int main() { int t; scanf("%d%d", &n, &t); for (int i = 0; i < n; i++)scanf("%s", s[i]); int i, j; while (t--) { int c1, c2; memset(fuck, 0, sizeof(fuck)); cnt = 1; scanf("%d%d",&c1,&c2); fuck[c1 - 1][c2 - 1] = true; dfs(c1 - 1, c2 - 1); printf("%d\n", cnt); } return 0; }
2、改进版
要确定:每个联通区域的答案是一样的,就好办了。
核心代码:
void dfs(int x, int y,int d) { for (int k = 0; k < 4; k++) { int tox = x + dir[k][0], toy = y + dir[k][1]; if (!fuck[tox][toy] && s[x][y] != s[tox][toy] && (tox >= 0 && tox < n && toy >= 0 && toy < n)) { cnt++; fuck[tox][toy] = d; dfs(tox, toy, d); } } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!fuck[i][j]) { fuck[i][j] = d;//d表示第几个连通区域 cnt = 1; dfs(i, j, d); ans[d++] = cnt; } } }
算是比较特殊的一种打表吧。
#include <iostream> #include <string.h> #include <stdio.h> int cnt,n; int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} }; int fuck[1005][1005]; int ans[1000005]; char s[1005][1005]; void dfs(int x, int y,int d) { for (int k = 0; k < 4; k++) { int tox = x + dir[k][0], toy = y + dir[k][1]; if (!fuck[tox][toy] && s[x][y] != s[tox][toy] && (tox >= 0 && tox < n && toy >= 0 && toy < n)) { cnt++; fuck[tox][toy] = d; dfs(tox, toy, d); } } } int main() { int t; scanf("%d%d", &n, &t); for (int i = 0; i < n; i++)scanf("%s", s[i]); int i, j, d = 1; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!fuck[i][j]) { fuck[i][j] = d; cnt = 1; dfs(i, j, d); ans[d++] = cnt; } } } while (t--) { int c1, c2; scanf("%d%d",&c1,&c2); printf("%d\n", ans[fuck[c1 - 1][c2 - 1]]); } return 0; }