第七天:走出泥潭(深度优先搜索+链表+图论)

本文通过一道“走出泥潭”的题目,探讨了如何使用链表和搜索算法找到从起点到终点的路径。文章详细介绍了两种解题思路:深度优先搜索和链表动态规划/回溯,适合对链表和搜索算法感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天是释然发题解的第七天,以后每一天都会和大家分享学习路上的心得,希望和大家一起进步,一起享受coding的乐趣。
本文约1800字,预计阅读6分钟
前天我们学习了链表,忘记的小伙伴们可以看一下哦:

初识链表

今天我们来聊一聊的链表的相关题目,明天和大家分享二分和贪心的相关知识:

题目来源:我校OJ题库

题目描述:
探险队要穿越泥潭,必须选择可踩踏的落脚点。可是泥潭面积很大,落脚点又实在少得可怜,一不小心就会深陷泥潭而无法脱身。侦查员费尽周折才从老乡手里弄到了一份地图,图中标出了落脚点的位置,而且令人震惊的是:泥潭只有一条穿越路线,且对于nxm的地图,路线长度为n+m-1!请编程为探险队找出穿越路线。

输入描述:
两个整数n和m,表示泥潭的长和宽。下面n行m列表示地形(0 表示泥潭,1 表示落脚点)

输出描述:
用坐标表示穿越路线,坐标之间用>分隔

样例输入:
6 9

1 1 1 0 0 0 0 0 0

0 0 1 1 1 0 0 0 0

0 0 0 0 1 0 0 0 0

0 0 0 0 1 1 0 0 0

0 0 0 0 0 1 1 1 1

0 0 0 0 0 0 0 0 1

样例输出:
(1,1)>(1,2)>(1,3)>(2,3)>(2,4)>(2,5)>(3,5)>(4,5)>(4,6)>(5,6)>(5,7)>(5,8)>(5,9)>(6,9)

注意:N<=100
什么意思呢?就是从从(1,1)开始走到(n,m),我们可以用链表和搜索去解决

解题思路1:深度优先搜索

一看这个题,这不是标准的深度优先搜索的题目嘛?(不知道的也没关系,我们主要是来用链表走的,后面也会有相应的文章)
而这种搜索属于非常简单的搜索,输出也很方便,但是后面的题目会越来越难

//用map来保存地图
int map[N][N];
//保存左右坐标,我们用结构体数组更方便
struct tree
{
    int l;
    int r;
}node[N];
void dfs(int x,int y)
{
	//一定要判断边界条件,什么时候停止搜索
    if(x==n&&y==m)
    {
        for(int i=1;i<num;i++)
        {
            cout<<"("<<node[i].l<<node[i].r<<")"<<">";
            cout<<"("<<x<<","<<y<<endl;
        }
    }
    else
    {
        if(map[x][y]==1&&x<=n&&y<=m)
        {
            node[num].l=x;
            node[num].r=y;
            num++;
            //两个方向
            dfs(x+1,y);
            dfs(x,y+1);
        }
    }

解题思路2:链表

这道题可以用链表做,这道题题意是从(1,1)开始走到(n,m)的,并且是只能向右或者向下走,因此这道题才可以使用链表去解决。逐个保存结点,然后输出整链

//我们先写一个创建结点的结构
struct node
{
	int left;
	int right;
	struct node *next;	
};
//创建一个头结点
	struct node *head,*p,*q;
	head=(struct node *)malloc(sizeof(struct node));//动态分配内存
	head->left=1;
	head->right=1;
	head->next=NULL;
	q=head;

如果我们直接保存头结点作为第一个点,那么这时(1,1)我们已经储存过了,所以后来的结点要把这个跳过

//用循环来创建多个结点
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)	
	{	//说过了只有向右和向下的时候才能这样去搜索
		cin>>x;
		if(x==1&&i+j!=2{
		p=(struct node *)malloc(sizeof(struct node));//动态分配内存
		p->left=i;
		p->right=j;
		q->next=p;
		p->next=NULL;
		q=p;
		}
	}
	}
输出:从头指针开始找
p=head;
while(p)
{
	cout<<"p.left<<","<<p.right<<")"<<">";
	p=p.next;
	if(p.next==Null)//最后一步输出要注意
	{
	cout<<"p.left<<","<<p.right<<")";
	break;
	)
}

好了,今天的有关走出泥潭的知识就到这里。
释然每天发布一点自己学习的知识,希望2年后我们也能在ACM的赛场上见面,一起去追寻自己的程序猿之路吧!

后期也会和大家一起分享学习心得和学习经验呢,明天我们不见不散哦!

下期预告:

动态规划/回溯

如果大家有什么建议或者要求请后台留言,释然也想和大家一起进步呀!
联系方式:shirandexiaowo@foxmail.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Shirandexiaowo

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值