算法八:试探(回溯)

试探法也称为回溯法,它是一种系统地搜索问题解的方法,该算法设计思想适用范围相当广泛。试探法是搜索算法中的一种控制策略。它的基本思想是:从问题的某一种状态(一般是默认的初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候,先退几步,接着从另一种可能的“状态”出发,继续搜索,直到所有的“路径”都尝试过。

对于常见的迷宫问题,就可使用试探法来求解,具体过程为:进入迷宫后,先随意选择一个前进方向,一步步向前试探前进,如果碰到死胡同,说明前进方向已无路可走,这时,首先看其他方向是否还有路可走,如果有路可走,则沿该方向再向前试探;如果已无路可走,则返回一步,再看其他方向是否还有路可走;如果有路可走,则沿该方向再向前试探。按此原则不断试探、回溯、再搜索,直到找到新的出路或从原路返回入口处无解为止。

一般性模板:
在这里插入图片描述

例题一、生成彩票号码组合

常见的彩票号码都是由一些数字组成的,生成彩票号码其实就是将所有数字进行不同的组合。例如,假设有一种彩票,每注由7个1~29的数字组成,且这7个数字不能相同,编写程序生成所有的号码组合。

很多人看到这题首先会想到写七层嵌套循环得出结果,但是代码会很烦琐,复杂度也高

但这题用回溯更有意思

首先我们知道有7个彩票号码各不相同,而取值是1~29,那么我们可以从第七个数(数组最末尾的6)开始,首先最外层是combine(29,7)到内层combine(28,6),…,combine(23, 1),然后输出,接着循环让数组最末尾的数字递减,依次类推,数组左边的数永远比右边大同时也不会重复,这样我们就可以得到需要的组合,但是时间复杂度太大,一时半会运行不完

详细C代码如下:

#include<stdio.h>

#define MAXN 7
#define NUM 29
int num[NUM];
int lottery[MAXN];
void combine(int n, int m){
	int i, j;
	for(i = n; i >= m; i--){
		lottery[m - 1] = num[i - 1];
		if(m > 1)
			combine(i - 1, m - 1);
		else{
			for(j = MAXN - 1; j >= 0; j--){
				printf("%3d", lottery[j]);
			}
 			getch();	
			printf("\n");
		}
	}
}

int main(){
	int i, j;
	for(i = 0; i < NUM; i++){
		num[i] = i + 1;
	}
	for(i = 0; i < MAXN; i++)
		lottery[i] = 0;
	combine(NUM, MAXN);
	getch();
	return 0;
}

部分运行结果如下:
在这里插入图片描述

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值