每日一题(1.4)解析

这篇博客讨论了一个关于二维数组的问题,目标是确定最少需要添加多少个'X'字符才能使两个含有'X'的连通块通过水平或垂直方向相连。博主提出了一种基于深度优先搜索(DFS)的解决方案,首先用DFS给两个连通块染色,并分别存储它们的坐标。随后,通过计算所有可能的连通路径(即两点间曼哈顿距离减1),找出最短路径,更新最小值。文章给出了C++代码实现,并在50x50的数组范围内进行操作。
摘要由CSDN通过智能技术生成

由题意可知,该题的目的是保证有2个X字符的连通块,只能横着或者竖着添加字符,最后寻找最少加几个x字符可以将两个连通块连接起来。

由于该题的数据范围为50*50一共2500个点,所以可以直接枚举。利用dfs将两个连通块分开,表上不同的记号。

然后任意多个将两个连通块连接的x构成的折线等价于这两个点之间的曼哈顿距离-1,所以直接枚举两个连通块之间的点的曼哈顿距离是多少,然后更新最小答案即可。

下面给出P(x_{P},y_{P})Q(x_{Q},y_{Q})两点间的曼哈顿距离的计算方法:

Manhattan(P,Q)=|x_{P}-x_{Q}|+|y_{P}-y_{Q}|

c++代码参考:

#include<bits/stdc++.h>
using namespace std;
const int N=55;
char ma[N][N];  //存放地图
int vis[N][N];
int n,m;
int px[4]={0,0,1,-1},py[4]={1,-1,0,0};
int mi=1e5;
vector<pair<int,int>>p1,p2;
void dfs(int x,int y,int k)  //分别染色两个斑点,放到两个不同的vector数组里
{
    if(vis[x][y])return ; //说明染过
    vis[x][y]=k;
    if(k==1)p1.push_back({x,y});
    else p2.push_back({x,y});
    for(int i=0;i<4;i++)
    {
        int ux=x+px[i],uy=y+py[i];
        if(ux<1||uy<1||ux>n||uy>m||ma[ux][uy]=='.')continue;
        else dfs(ux,uy,k);
    }
}
int main()
{
    cin>>n>>m;
    int k=1;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
         cin>>ma[i][j];
    //先利用dfs将两个斑点染色
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(ma[i][j]=='X'&&!vis[i][j])
            {
                dfs(i,j,k);
                k++;
            }
        }
    }
    for(int i=0;i<p1.size();i++)  //暴力枚举两个斑点数组里每个坐标之间的曼哈顿距离-1
    {
        for(int j=0;j<p2.size();j++)
        {
            mi=min(mi,abs(p1[i].first-p2[j].first)+abs(p1[i].second-p2[j].second)-1);
        }
    }
    printf("%d",mi);
    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值