Elegant Showroom

文章描述了一种使用广度优先搜索(BFS)解决字符矩阵中最短路径的问题,矩阵中的字符表示不同类型的移动代价。起点到矩阵边界上标记为D的点的最短距离是目标。题目涉及图论中的最短路算法,并提供了AC代码示例。
摘要由CSDN通过智能技术生成

题目链接

题意:给出一个字符矩阵,#代表不可走,D代表经过此处不算距离,c代表经过此处距离+1,给出一个起点,要求求出到矩阵边界处的D的最短距离,矩阵边界一定由#和D组成

思路:bfs,每一个点不一定只更新一次,所以不需要vis数组,松弛每个点时如果此点到起始点的距离+到临点的距离大于临点到起始点的距离,则更新临点的距离,并将临点更新后的状态加入队列,(bfs中,队列存储的是更新过的点,也就是需要松弛的点),每次到矩阵边界如果此处为D,则更新结果,结果取最小值

实际上这题就是一个多终点的最短路,这个bfs跟最短路的代码有点像

ac代码:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define INF 0x3f3f3f3f
#define pb push_back
#define int long long
#define Mirai ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef pair<int,int> pii;
const int N=410;
int n,m,x,y;
char mp[N][N];
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
struct Node//更新队列中的点要记录坐标以及更新过后的距离
{
    int x,y;
    int d;
};
int dist[N][N];//没个点到起点的最小距离
int bfs()
{
    int res=INF;
    queue<Node> q;//q中存储的是更新过的点,也就是距离变小的点,也就需要用这些距离变小的点去更新他的临点
    memset(dist,INF,sizeof dist);
    dist[x][y]=1;//初始点也算一个移动,所以初始化为1
    q.push({x,y,dist[x][y]});
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        if(t.d>=res)continue;//如果当前点的最小距离已经大于已知结果的话则不用再更新了(此处优化可以加快一倍的速度)
        for(int i=0;i<4;i++)
        {
            int tx=t.x+dx[i],ty=t.y+dy[i];//移动到下一位置
            if(mp[tx][ty]=='#'||tx<0||tx>=n||ty<0||ty>=m)continue;//非法位置跳过
            if(tx==0||tx==n-1||ty==0||ty==m-1)res=min(res,t.d);
            int dd=t.d;//dd代表临点到起点的距离,如果下一个点为D则距离相等
            if(mp[tx][ty]=='c')dd++;//如果这个点为c则距离+1
            if(dd<dist[tx][ty])//如果距离小于当前此点距离起点的距离,则更新掉此点的距离,更新之后加入更新队列
            {
                dist[tx][ty]=dd;
                q.push({tx,ty,dist[tx][ty]});
            }
        }
    }
    return res;
}
void solve()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>mp[i][j];
    cin>>x>>y;
    x--,y--;//输入给的是从1,1开始的点,而此处的图是从0,0开始存的,所以要-1
    int res=bfs();
    if(res!=INF)cout<<res<<endl;
    else cout<<0<<endl;//如果结果为正无穷的话则说明没有更新出合法结果,则输出0
}
signed main()
{
    Mirai;
    int T=1;
    //cin>>T;
    while(T--)
    {
        solve();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ggplot2是一种用于绘制优雅图形的R语言包。它提供了一种基于图层的绘图系统,使得用户可以通过简单的代码创建复杂美观的图形。 首先,ggplot2采用了一种统一的语法,即“建立-添加图层-调整细节”的方式。用户只需通过一个ggplot()函数建立一个图形对象,然后通过不同的geom_函数来添加不同的图层,例如,geom_point()用于添加散点图,geom_line()用于添加线图等。这种语法设计使得代码结构清晰易懂,用户可以更好地组织和管理绘图代码。 其次,ggplot2提供了丰富的绘图选项,使得用户可以轻松调整图形的外观。用户可以通过使用scale_函数来调整颜色、尺寸、填充等属性,还可以通过theme_函数来修改坐标轴、标题、背景等元素。ggplot2还支持自定义主题和自定义图层,用户可以根据自己的需求定制个性化的图形。 另外,ggplot2还提供了数据的分组和聚合功能,使得用户可以轻松绘制分组柱状图、箱线图等图形。用户可以通过在aes()函数中指定分组变量来实现数据分组,还可以使用stat_函数来进行聚合操作,例如,使用stat_summary()函数计算均值、中位数等统计量并绘制到图形中。 最后,ggplot2还支持数据的层次化可视化,使得用户可以轻松绘制多个图形并将其组合到一个图形对象中。用户可以使用facet_grid()将数据按照一个或多个变量划分成多个小图,并可以通过coord_函数来调整子图之间的间距和位置。这使得用户可以在一个图形中同时展示多个变量的关系,更好地理解数据。 综上所述,ggplot2通过其简洁的语法、丰富的绘图选项、分组聚合功能和层次化可视化功能,提供了一种优雅的方式来创建美观、易懂的图形,使得用户可以更好地探索和展示数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值