类似星穹铁道的(简化版)电路连通算法?

文章介绍了如何运用深度优先搜索(DFS)算法解决类似星穹铁道游戏中电路连接的问题。通过创建线路模型,确定不同线路的连接规则,从起点开始寻找到达终点的路径。代码示例展示了如何实现这一过程,包括边界条件检查、线路使用标记以及线路类型判断等关键步骤。
摘要由CSDN通过智能技术生成

        本来在学习dfs相关算法,在书上看到了一个水管连通的例子,恰好最近又玩过星穹铁道,我记得里面有一个小任务就是帮助NPC连接电路,和算法书上涉及到的算法很相似,感觉挺有意思的,就把书上的算法小改了一下。

        这里我们以书上的类型为例(简单一些QAQ),总共有6种线路类型,和4个连接的朝向(上下左右)。要选择合适的线路型号,从而找出一条连接起点和终点的通路。

话不多说,以上图的起点和终点位置为例,上代码:

#include <iostream>

using namespace std;

int a[51][51];//假设线路大小不超过50*50
int book[51][51];//标记线路是否使用过
int n, m, flag = 0;//flag用来判断是否找到了一条线路

struct node
{
    //横纵坐标
    int x;
    int y;
    //线路型号
    int style;
}s[100];
int top = 0;

//使用DFS算法
void dfs(int x, int y, int front, int style)//参数解释:x, y是当前线路的位置坐标,front是前一条线路接入的方向,style前一条线路的型号
{
    //此处特别声明,因为每次线路连接好后,要传入此线路连接的下一个点的坐标
    //所以当连接到终点时,需要判断的是连接终点的下一个点的坐标
    //此例子中终点的位置在(n,m)并且线路终点在右边,所以要判断y与m + 1的关系
    //此处判断根据终点的具体位置变化
    if(x == n && y == m + 1)
    {
        //找到了线路
        flag = 1;
        //记录线路型号
        s[top].style = style;
        //输出结果
        for(int i = 1; i <= top; i++)
        {
            cout << "(" << s[i].x << "," << s[i].y  << ")"<< "   style: " << s[i].style << endl;
        }
        return ;
    }

    //判断是否越界
    if(x < 0 || x > n  || y < 0 || y > m )
    {
        return ;
    }
    //判断此线路是否在路径中已经使用过
    if(book[x][y] == 1)
    {
        return ;
    }
    //标记当前线路
    book[x][y] = 1;

    //将当前的线路信息入栈(包括坐标和线路类型)
    top++;
    s[top].x = x;
    s[top].y = y;
    //style是前一条线路的型号,所以这里要top - 1来使线路坐标与线路型号相匹配
    s[top - 1].style = style;
    
    //当线路为直线的情况
    if(a[x][y] >= 5 && a[x][y] <= 6)
    {
        if(front == 1)//从左边接入线路
        {
            dfs(x, y + 1, 1, 5);//只能采取5号类型的线路
        }
        if(front == 2)//从上方接入线路
        {
            dfs(x + 1, y, 2, 6);//只能采取6号类型的线路
        }
        if(front == 3)//从右边接入线路
        {
            dfs(x, y - 1, 3, 5);//只能采取5号类型的线路
        }
        if(front == 4)//从下方接入线路
        {
            dfs(x - 1, y, 4, 6);//只能采取6号类型的线路
        }
    }

    //当线路为弯曲的情况
    if(a[x][y] >= 1 && a[x][y] <= 4)
    {
        if(front == 1)
        {
            dfs(x + 1, y, 2, 3);//3号线路
            dfs(x - 1, y, 4, 4);//4号线路
        }
        if(front == 2)
        {
            dfs(x, y + 1, 1, 1);//1号线路
            dfs(x, y - 1, 3, 4);//4号线路
        }
        if(front == 3)
        {
            dfs(x - 1, y, 4, 1);//1号线路
            dfs(x + 1, y, 2, 2);//2号线路
        }
        if(front == 4)
        {
            dfs(x, y + 1, 1, 2);//2号线路
            dfs(x, y - 1, 3, 3);//3号线路
        }
    }

    //取消标记,将当前尝试坐标出栈
    book[x][y] = 0;
    top--;
    return ;
}

int main()
{
    //输入线路板大小
    //初始化线路板
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1 ; j <= m; j++)
        {
            cin >> a[i][j];
        }
    }
    //从(1,1)开始,线路从左边接入,由于是线路起点,所以没有线路型号
    dfs(1, 1, 1, 0);
    //判断是否找到可行线路
    if(flag == 0)
    {
        cout << "Fail" << endl;
    }
    return 0;
}

        代码中的注释应该比较详细了,所以我也不过多赘述。星穹铁道中的电路有6个朝向,而例子中只有4个朝向,算是一个简化版吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值