PTA 寻宝图

本文介绍了如何使用深度优先搜索解决寻宝图问题,通过DFS遍历网格寻找相连的非零区域,并提出了空间复杂度优化、避免重复访问、迭代实现、高效数据结构和并行处理等优化思路。
摘要由CSDN通过智能技术生成

今天是PTA题库解法讲解的第十五天,今天我们要讲解寻宝图,题目如下:

解题代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
vector<int>f[N],st[N];
int cnt,sum;
bool flag;
int n,m;
int dx[] = {-1,0,1,0},dy[] = {0,1,0,-1};
void dfs(int x,int y)
{
    st[x][y] = true;
    if(f[x][y] > 1) flag = true;
    for(int i = 0;i < 4;i++)
    {
        int xx = x + dx[i],yy = y + dy[i];
        if(xx >= 1 && xx <= n&&yy >= 1&&yy <= m&&f[xx][yy]&&!st[xx][yy])
        {
            if(f[xx][yy] > 1) flag = true;
            dfs(xx,yy);
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i = 1;i <= n;i++)
    {
        f[i].push_back(0);
        st[i].push_back(0);
        for(int j = 1;j <= m;j++)
        {
            char c;
            cin>>c;
            f[i].push_back(c-'0');
            st[i].push_back(0);
        }
    }
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= m;j++)
        {
            if(f[i][j] && !st[i][j])
            {
                flag = false;
                sum++;
                dfs(i,j);
                if(flag) cnt++;
            }
        }
    cout<<sum<<" "<<cnt;
    return 0;
}

思路:

这段代码的目的是在一个由数字组成的网格上寻找由相连的非零数字组成的区域(这里称为“宝藏”),并且特别标记包含数字大于1的区域。代码的基本思路是使用深度优先搜索(DFS)遍历网格,对每个未被访问过的非零点执行DFS,以找到所有相连的区域。如果一个区域包含任何大于1的数字,则将其标记为特殊区域。最后,输出两个数:总的区域数和包含大于1的数字的区域数。

优化想法:

以下是一些潜在的优化方向:

  1. 空间复杂度优化:在当前的实现中,fst使用了vector<int>的数组来存储网格和状态,这导致较高的空间复杂度。一个可能的优化是使用单个二维vector来存储网格状态,减少内存使用。

  2. 避免重复访问:在DFS中,对于已经访问过的点,你已经通过st[x][y]进行了标记以避免重复访问,这个做法是合适的,但在实际编码时可以考虑使用更加直观的数据结构,比如直接的二维vector<bool>来存储访问状态。

  3. 迭代而非递归:对于深度优先搜索,递归是一种自然且简单的实现方式,但在极端情况下可能会导致栈溢出。一种替代方法是使用迭代加栈的方式实现DFS,这样可以手动控制栈的大小,避免溢出。

  4. 更高效的数据结构:对于大型数据,使用动态数组(如std::vector)可能不是最高效的选择。考虑到nm的最大值,可以使用固定大小的数组(如果问题描述中给出了上限),或者使用更高效的数据结构,如稀疏矩阵(如果大部分元素都是零)。

  5. 并行处理:如果输入网格很大,可以考虑将网格分割成几个部分,使用并行算法(例如OpenMP)来同时处理这些部分。这种方法可以显著减少运行时间,特别是在多核处理器上。

  6. 启发式搜索:虽然对于此问题DFS是一个直接的解决方案,但在某些情况下,根据具体问题特点使用启发式搜索算法(如A*搜索)可能更有效。

提交代码:

今日题解到此位置~

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶秋学长

走过路过不要错过

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值