题解 [ABC311D] Grid Ice Floor

题意

你在一个 N×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;
}
posted @   Chen_Jinhui  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

一言

我想让自己强大起来,因为至少我已经有幸和想要保护的人相遇了。
——夏目友人帐
点击右上角即可分享
微信分享提示