sicily 1152&1153之递归结束

本文详细介绍了深搜在解决特定类型问题时的结束问题,提供了两种解决方法,并通过代码实例展示了如何解决1152和1153两个相似但数据量不同的问题。重点在于理解深搜与广搜的递归特性及如何正确跳出递归,以避免无限循环。

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

题目在这里11521153

这两道是一样的题目,只是1153数据量比较大,需要剪枝,就是优先搜索出度比较少的节点。然后,写的时候参考了这个代码,尊重原创,链接在此点击打开链接


这里要说的是关于深搜的结束问题。

涉及到深搜和广搜,都会运用到递归的特性,而由于每次递归相当于调用子函数(只不过这个函数是本身),因此其遵守计算机组成原理里描述的“哪里中断、哪里返回”的原则。因此,当我们用深搜(递归)来解决类似最短路径等不需要全部遍历完的问题时,需要在满足条件的时候跳出递归。正如前面所说,递归遵守“哪里中断、哪里返回”,因此处理不好,很容易造成无法在需要停止的时候停止递归而一直递归下去。

这里提供两种解决的方法,一、把你要递归的函数的返回值改成bool,把递归的式子放到if条件里;二、添加一个全局布尔变量,初始值false,满足终止条件的时候改回true,在递归的式子下面添加一个判断该变量的if语句,如果为true,则return。第一种方法可以参考下面我贴出的代码,第二种就自行脑补了


其实,怎么说呢,写代码不是说懂得原理就行,有的时候还需要去真正的敲出来,技巧总是在实战中总结出来的。

1152

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>

using namespace std;

int direction[8][2] = { { -2, -1 }, { -1, -2 }, { 2, 1 }, { 1, 2 }, { -2, 1 }, { -1, 2 }, { 2, -1 }, { 1, -2 } };
bool visited[6][7];


bool judege(int x, int y)
{
	return x >= 1 && x <= 5 && y >= 1 && y <= 6 && visited[x][y] == false;
}


int get_degree(int x, int y)
{
	int re = 0;
	int t_x, t_y;
	for (int i = 0; i < 8; i++)
	{
		t_x = x + direction[i][0];
		t_y = y + direction[i][1];
		if (judege(t_x, t_y))
			re++;
	}
	return re;
}


struct Node
{
	int x;
	int y;
	int out_degree;

	Node(int x, int y)
	{
		this->x = x;
		this->y = y;
		this->out_degree = get_degree(x, y);
	}
};

bool cmp(Node n1, Node n2)
{
	return n1.out_degree < n2.out_degree;
}


int road[30];


bool dfs(Node start, int step)
{
	int t_x, t_y;
	vector<Node> buffer;

	visited[start.x][start.y] = true;
	road[step] = (start.x - 1) * 6 + start.y;

	if (step == 29)
		return true;

	for (int i = 0; i < 8; i++)
	{
		t_x = start.x + direction[i][0];
		t_y = start.y + direction[i][1];
		if (judege(t_x, t_y))
			buffer.push_back(Node(t_x, t_y));
	}

	sort(buffer.begin(), buffer.end(), cmp);

	for (int i = 0; i < buffer.size(); i++)
	{
		if (dfs(buffer[i], step + 1))
			return true;
	}
	visited[start.x][start.y] = false;
	return false;
}


void output()
{
	cout << road[0];
	for (int i = 1; i < 30; i++)
		cout << " " << road[i];
	cout << endl;
}


int main()
{
	int origin, origin_x, origin_y;
	while (cin >> origin && origin != -1)
	{
		origin_x = origin % 6 == 0 ? origin / 6 : origin / 6 + 1;
		origin_y = origin % 6 == 0 ? 6 : origin % 6;

		memset(visited, false, sizeof(visited));

		dfs(Node(origin_x, origin_y), 0);
		
		output();
	}
	//system("pause");
	return 0;
}

1153

把上面的数值稍微改一下就能通过1153了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值