水管工游戏--dfs的应用

水管工游戏

要求

如图只有两种管道,求如何摆放让管道从左上角到右下角连通?0代表树木,1~6代表管道的不同摆放方式,为了程序处理方便,将进水口在左边用1表示,上边用2表示,右边用3表示,下边用4表示。

思路

使用深度优先搜索解决,先判断当前管道的类型,然后根据进水口的方向,决定下一个管道的位置和进水口的方向。使用栈保存路径。

代码

#include <stdio.h>

#define N 5
#define M 4

int a[N][M] = {
                {5, 3, 5, 3},
                {1, 5, 3, 0},
                {2, 3, 5, 1},
                {6, 1, 1, 5},
                {1, 5, 5, 4},
               };

int b[N][M] = {0};
int flag = 0;

struct node 
{
    int x;
    int y;
};

struct node stack[100];
int top = 0;

void push(int x, int y) {
    stack[top].x = x;
    stack[top].y = y;
    top++;
}

struct node pop() {
    top--;
    return stack[top];
}

void print_a() {
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < M; ++j)
        {
            printf("%3d ", a[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

void print_b() {
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < M; ++j)
        {
            printf("%3d ", b[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

void print_s() {
    for (int i = 0; i < top; ++i) {
        printf("(%d %d) ", stack[i].x, stack[i].y);
    }
    printf("\n");
}

void dfs(int x, int y, int front) {  // 1:进水口在左边 2:上 3:右 4:下

    if (x == N - 1 && y == M) {
        flag = 1;
        print_s();
        return;
    }

    if (x < 0 || x > N || y < 0 ||  y > M) {
        return;
    }

    if (b[x][y] == 1) {
        return;
    }
    b[x][y] = 1;

    push(x, y);  // 压栈

    if (a[x][y] >= 5 && a[x][y] <=6 ) { // 当前管道是直管
        if (front == 1) {
            dfs(x, y+1, 1);
        }
        if (front == 2) {
            dfs(x+1, y, 2);
        }
        if (front == 3) {
            dfs(x, y-1, 3);
        }
        if (front == 4) {
            dfs(x-1, y, 4);
        }
    }

    if (a[x][y] >= 1 && a[x][y] <= 4) { // 当前管道是弯管
        if (front == 1) {
            dfs(x+1, y, 2);  // 3号状态
            dfs(x-1, y, 4);  // 4号状态
        }
        if (front == 2) {
            dfs(x, y+1, 1);  // 1号状态
            dfs(x, y-1, 3);  // 4号状态
        }
        if (front == 3) {
            dfs(x-1, y, 4);  // 1号状态
            dfs(x+1, y, 2);  // 2号状态
        }
        if (front == 4) {
            dfs(x, y+1, 1);  // 2号状态
            dfs(x, y-1, 3);  // 3号状态
        }
    }
    b[x][y] = 0;
    pop();  // 出栈
}

int main()
{
    dfs(0,0, 1);
    if (flag == 0) {
        printf("not found \n");
    } else {
        printf("found \n");
    }
    return 0;
}

总结

为什么dfs可以用递归的方式和栈的方式实现?

因为函数的调用也是通过栈的操作方式实现的,一个函数被调用时将其压栈,函数返回时出栈。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值