题意:给定一个n*m的地图,有k次查询。每次查询,询问位置(x, y)(保证为字符.) 周围有多少个*。
思路:DFS查询连通的.周围有多少*,用时间戳dfsclock来记录DFS的次数。对当前的dfsclock,把DFS到的所有位置(x, y) 标记为time[x][y]=dfsclock,DFS结束后,用数组num[dfsclock]记录连通块周围*的个数。 查询时,输出
num[time[x-1][y-1]]就可以了。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-4
#define MAXN (10000+10)
#define MAXM (1000000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 100000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
using namespace std;
char str[1010][1010];
int num[1000100];
int time[1010][1010];
bool vis[1010][1010];
int sum;
int Move[4][2] = {0,1, 0,-1, 1,0, -1,0};
int n, m;
bool judge(int x, int y){
return x >= 0 && x < n && y >= 0 && y < m;
}
int dfs_clock;
void DFS(int x, int y)
{
vis[x][y] = true; time[x][y] = dfs_clock;
for(int k = 0; k < 4; k++)
{
int next_x = x + Move[k][0];
int next_y = y + Move[k][1];
if(!judge(next_x, next_y) || vis[next_x][next_y])
continue;
if(str[next_x][next_y] == '*')
sum++;
else
DFS(next_x, next_y);
}
}
int main()
{
int k;
Ri(n); Ri(m); Ri(k);
for(int i = 0; i < n; i++)
Rs(str[i]);
CLR(vis, false); dfs_clock = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(str[i][j] == '.' && !vis[i][j])
{
sum = 0;
++dfs_clock;
DFS(i, j);
num[dfs_clock] = sum;
}
}
}
while(k--)
{
int x, y;
Ri(x); Ri(y);
Pi(num[time[x-1][y-1]]);
}
return 0;
}