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;
}

猜你喜欢

转载自www.cnblogs.com/LLLAIH/p/11285533.html