标签: 深度优先搜索、连通块
【题解】
采用dfs深搜,但是如果对每个要求点都深搜一次应该会超时,优化方法是采用连通块的思想。
题目是说从一格开始能移动到多少格,可以有很多岔路,深搜时不用回溯,一直搜就行。这些岔路上所有的点构成连通块,连通块任意一点能移动的格数是相同的(这个很好理解,简单来说就是你能到我这,那么我也能到你那)。
【代码】
#include <iostream>
#include <cstring>
using namespace std;
int n, m, x, y, loc[1005][1005], ans[100005];//loc记录是否走过,ans记录能走的格数
char ch[1005][1005]; //ch保存迷宫的点
void dfs(int x, int y, int c, int i)
{
if (x < 0 || y < 0 || x >= n || y >= n || loc[x][y] != -1 ||
ch[x][y]-'0'!= c) return;
loc[x][y] = i; //连通图使用的重点
ans[i]++;
//上下左右四个方向
//采用!c,因为第一次的dfs和后面的dfs有点不同(ch[x][y]-'0'!= c)
dfs(x, y - 1, !c, i);
dfs(x - 1, y, !c, i);
dfs(x + 1, y, !c, i);
dfs(x, y + 1, !c, i);
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> ch[i];
memset(loc, -1, sizeof(loc));
for (int i = 0; i < m; i++)
{
cin >> x >> y;
x--; y--; //输入的是1~n,存储计算时采用的是0~n-1
if (loc[x][y] == -1) { //等于-1说明还没搜到过
dfs(x, y, ch[x][y] - '0', i);
}
else { //不等于-1说明在连通图中
ans[i] = ans[loc[x][y]];
}
}
for (int i = 0; i < m; i++)
cout << ans[i] << endl;
return 0;
}