codeforces 598D Igor In the Museum(dfs)
http://codeforces.com/problemset/problem/598/D
题意:给你一个'.'坐标,问你她能看见多少幅画?'.'代表可通行的点,'*'代表不可通行的点,'.'与'*'相邻的地方都挂着一副画
思路:找到每一个'.'的连通块,并作上标记,所有的'.'与'*'相邻的总数即是这个连通块里每一个'.'所能看见的画的数目
#include <cstdio> #include <algorithm> #include <iostream> #include <vector> #include <cstring> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; string a[1005]; int dir[4][2] = {0,1,0,-1,1,0,-1,0}; int countt,vis[1005][1005],num[1005][1005],ans[1005],sum; void _dfs(int x,int y) { vis[x][y] = sum;//给连通的点做上标记sum int fx,fy,k; for( k=0;k<4;k++) { fx = x + dir[k][0]; fy = y + dir[k][1]; if(a[fx][fy] == '.' && !vis[fx][fy]) { countt += num[fx][fy];//加上连通的点的画的数量 _dfs(fx,fy); } } } int main() { int n,m,k; while(cin >>n >>m >>k) { for(int i = 0;i< n;i++) { cin >> a[i]; } mem(num,0); for(int i = 0;i<n;i++) { for(int j=0;j<m;j++) { if(a[i][j] == '.')//统计'.'相邻的'*'的数量 即画的数量 { if(a[i-1][j] == '*') num[i][j]++; if(a[i+1][j] == '*') num[i][j]++; if(a[i][j+1] == '*') num[i][j]++; if(a[i][j-1] == '*') num[i][j]++; } } } int x,y; sum = 0; mem(vis,0); for(int i = 0;i<n;i++) { for(int j =0;j<m;j++) { if(a[i][j] == '.'&&!vis[i][j])//如果该点'.'还没有被连通 { sum++; countt = 0; countt += num[i][j];//加上起点的画的数量 _dfs(i,j); ans[sum] = countt;//将连通块所能看见的画的总数赋值给标记为sum的数组 } } } for(int i=0;i<k;i++) { cin >> x >> y; cout << ans[vis[x-1][y-1]] << endl; } } return 0; }