Igor In the Museum
Descriptions
给你一个n*m的方格图表示一个博物馆的分布图.
每个方格上用'*'表示墙,用'.'表示空位.
每一个空格和相邻的墙之间都有一幅画.
(相邻指的是上下左右相邻).
你可以从一个空格的位置走到相邻的空格位置.
现在你给你若干个(xi,yi)形式的询问,表示你现在在(xi,yi)这个位置(保证为空位)出发,问你从这个点出发你能看到多少幅画.
Input
第一行有3个整数n,m,k(3<=n,m<=1000,1<=k<=min(m*m,100000) ).
接下来有n行每行m个字符,每个字符为'.'或者'*'.
紧接着k行,每行两个整数xi,yi.Output
对于k个询问,输出相应的答案.
Examples
Input5 6 3
******
*..*.*
******
*....*
******
2 2
2 5
4 3
Output6
4
10Input4 4 1
****
*..*
*.**
****
3 2
Output8
题目链接
https://vjudge.net/problem/CodeForces-598D
不难的一个bfs,一直t在memset上,每次bfs是不需要memset标记数组的,只要你记录一下,每个点就只需要扫一次了,直接一整个幅地图按块bfs,即从这一块的"."出发,看到的都是ans副画,并且记录下来,最后直接输出即可。还不清楚可以参考代码
AC代码
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x,y) memset(x,y,sizeof(x))
#define Maxn 1005
using namespace std;
int n,m,k;
char mp[Maxn][Maxn];//存图
int vis[Maxn][Maxn];//标记"."是否走过
int step;//几副画
int dt[][2]= {{0,1},{0,-1},{1,0},{-1,0}};//四个方向
struct node
{
int x,y;
};
node now,net;
node road[1000005];//"."这个点的状态
int ans[Maxn][Maxn];//记录从(x,y)能看到几幅画
void judge(int x,int y)//(x,y)这四周有几幅画
{
for(int i=0; i<4; i++)
{
int tx=dt[i][0]+x;
int ty=dt[i][1]+y;
if(tx>=1&&ty>=1&&tx<=n&&ty<=m&&mp[tx][ty]=='*')
{
step++;
}
}
}
void bfs()
{
step=0;//几幅画
int cnt=0;//第几个"."
queue<node>q;
q.push(now);
judge(now.x,now.y);
vis[now.x][now.y]=1;
while(!q.empty())
{
now=q.front();
q.pop();
road[cnt++]=now;
for(int i=0; i<4; i++)//四个方向bfs
{
int tx=dt[i][0]+now.x;
int ty=dt[i][1]+now.y;
if(tx>=1&&ty>=1&&tx<=n&&ty<=m&&!vis[tx][ty]&&mp[tx][ty]=='.')
{
net.x=tx,net.y=ty;
q.push(net);
judge(tx,ty);
vis[tx][ty]=1;
}
}
}
for(int i=0; i<cnt; i++)//这一块的"."全部都能看见step副画
ans[road[i].x][road[i].y]=step;
}
int main()
{
MEM(vis,0);//初始化,存图
cin>>n>>m>>k;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
cin>>mp[i][j];
for(int i=1; i<=n; i++)//开始一块一块的找"."并且bfs
{
for(int j=1; j<=m; j++)
{
if(mp[i][j]=='.'&&!vis[i][j])
{
now.x=i,now.y=j;
bfs();
}
}
}
while(k--)
{
int x,y;
cin>>x>>y;
cout<<ans[x][y]<<endl;
}
return 0;
}
本文介绍了一个基于图遍历算法的编程问题解决方案。通过广度优先搜索(BFS),算法能够高效地计算从博物馆任意空位出发可见画作的数量。文中详细解释了如何避免重复计算,并附带了完整的AC代码。

被折叠的 条评论
为什么被折叠?



