题解 [ABC311D] Grid Ice Floor
题意
你在一个 $N \times M$ 的地图上,在地图上有两种地形:
- 冰块,用字符
.表示。 - 岩石,用字符
#表示。
你一开始在 $(2,2)$(保证为冰块),你可以向上下左右四个方向移动直到下一个运动的位置为岩石(中途不能停止),求你经过或停留的冰块数量。
分析
这个其实就是一道广度优先搜索。
和其他的题目处理略有些不同的地方在于,他不能在移动途中停留,这个特殊判断一下就可以了。
只有到了岩石前方,才能入队。
注意事项
由于本人设 $(0,0)$ 为坐标原点,故初始位置应为 $(1,1)$。
代码
//the code is from chenjh
#include<cstdio>
#include<queue>
#include<utility>
#define mp std::make_pair
#define x first
#define y second
typedef std::pair<int,int> PII;
int n,m;
char s[202][202];
const int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};//预处理方向数组,减少判断。
bool vis[202][202],vs[202][202];//前者为是否经过该点,后者是是否停留在该点上。
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) scanf("%s",s[i]);
std::queue<PII> Q;
Q.push(mp(1,1));//加入初始坐标。
for(PII u;!Q.empty();){
u=Q.front();Q.pop();
if(vs[u.x][u.y]) continue;
vs[u.x][u.y]=1;//标记当前位置停留。
for(int k=0,nx,ny;k<4;k++){
for(nx=u.x,ny=u.y;nx>=0&&nx<n&&ny>=0&&ny<m&&s[nx][ny]=='.';nx+=dx[k],ny+=dy[k])vis[nx][ny]=1;//标记当前位置经过。
nx-=dx[k],ny-=dy[k];//注意后退,因为此时可能已经越界。
if(!vs[nx][ny]) Q.push(mp(nx,ny));//没有停留过,再次扩展加入队列。
}
}
int sum=0;
for(int i=0;i<n;i++)for(int j=0;j<m;j++)sum+=vis[i][j];//计数。
printf("%d\n",sum);
return 0;
}

浙公网安备 33010602011771号