题目描述
烤乐滋是个调皮的小男孩,他不需要给大家留下深刻的印象,于是自暴自弃,把图漾中学教室的玻璃砸碎了。 图漾中学的教导处主任抓起一把戒尺就冲了过去,烤乐滋不得不逃向学校的小树林。
学校的小树林由于疏于管理,并不太茂密,供烤乐滋隐蔽的大树也比较少。烤乐滋知道,他离最近的一棵树的 距离越近,他有越大的概率躲过教导主任的追杀。但学校的小树林面积有点大,烤乐滋知道自己如果找出离每个位 置最近的一棵树,一定需要花很多的时间,自己的小命就不保啦。 学校的小树林可以抽象成一个 n m 的网格,每个 11 的格子为一个位置,每个位置有树、空地、障碍三 种形态,与一个格子距离为 1 的格子定义为它上下左右的四个格子。(边界除外),你不能走到有障碍的格子上面。
两个格子之间的距离定义为两个格子之间不经过障碍的最短路长度,如果两个格子不可达,那么我们定义它 们之间的距离为“GoDie”。
你要求出每个格子的危险值。一个非障碍格子的危险值定义为它离所有树的距离当中最小的那一个距离。在求 最小值的过程中,你可以视GoDie 为大于一切其他距离的一个值,如果这个格子离所有树的距离都为GoDie,那 这个格子的危险值也将是GoDie。
根据上面的定义,显然树格子的危险值为 0。
现在烤乐滋拥有了学校小树林的具体地图,他希望你告诉他每一个位置的危险值,以方便他挑选最佳隐蔽地点。
输入
第一行两个数 n,m。表示学校小树林的大小。
接下来 n 行,每行 m 个字符,描述了这个网格。
其中,“.”代表空地- “ *”代表树,“#”代表障碍。
保证没有多余空格,保证至少有一棵树
输出
输出 n 行,每行 m 个成分。对于第 i 行的第 j 个成分: 如果该格子为非障碍格子,输出其危险值,即最小距离或“GoDie”。 如果该格子为障碍格子,输出"ovo"不包含引号
每个成分之间用一个空格隔开。
*…
…#.
##…
0 1 2 3 4
0 1 2 ovo 5
ovo 0 ovo 7 6
提示
对于 30% 的数据,n,m ≤ 10。
对于 70% 的数据,n,m ≤ 50。
对于 100% 的数据,n,m ≤ 1000。
爆搜题,把每个是树的位置都入队,然后通过树的位置BFS,推出每个空位对于树的位置的距离
#include<bits/stdc++.h>
using namespace std;
char a[1500][1500];
int ans[1500][1500],vis[1500][1500];
int n,m;
int dx[4]={0,0,1,-1};//移动方向
int dy[4]={1,-1,0,0};//移动方向
struct node
{
int x;
int y;
};
queue<node>q;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]=='*')//树的位置
{
ans[i][j]=0;
node st;st.x=i;st.y=j;
q.push(st);
vis[i][j]=1;
}
if(a[i][j]=='#')ans[i][j]=-1;
if(a[i][j]=='.')ans[i][j]=1e9;
}
while(!q.empty())
{
node ne=q.front();q.pop();
for(int i=0;i<4;i++)//朝四个方向运动
{
int xx=ne.x+dx[i];
int yy=ne.y+dy[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&a[xx][yy]!='#'&&!vis[xx][yy])//如果没有走过,没有超边界 不是陷阱
{
vis[xx][yy]=1;
node k;k.x=xx;k.y=yy;
q.push(k);
ans[xx][yy]=ans[ne.x][ne.y]+1;//更新ans
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='*')cout<<0<<' ';//是树
if(a[i][j]=='.')
if(ans[i][j]==1e9)cout<<"GoDie ";//不可以到
else cout<<ans[i][j]<<' ';
if(a[i][j]=='#')cout<<"ovo ";
}
cout<<endl;
}
}