递归算法1加到100_「算法」北京大学算法基础—递归(1)

(干货菌:枚举和递归是所有算法的根基,所有算法也都是这两种思维的继续拓展。)

递归:某个函数直接或间接的调用自身。

f(x)=g(f(x-1)),已知f(0)的值和g(),就可以求出。

枚举是把一个问题划分为一组子问题(横向的),递归是把一个问题逐级分解成子问题(纵向的)。

06d1b8255bee9b226bcd14d444777ecf.png
ec47611435b8c45f55ad34a9ddafc3d3.png

阶乘的栈结构

解决:1、找出递归公式,2、找到递归终止条件。

小游戏:

4231c266e1a993405e21c1f62fedf235.png

游戏在一个分割成w*h个正方格子的矩形板上进行,每个正方格子上可以有一张游戏卡片,当然也可以没有。

问题描述(连连看):

当下面的情况满足时,认为两个游戏卡片之间有一条路径相连:

  • 路径只包含水平或者竖直的直线段
  • 路径不能穿过别的游戏卡片
  • 但是允许路径临时的离开矩形板
ae29d665e2dab6495ff2043658757e3f.png

输入:

  • ·输入包括多组数据:一个矩形板对应一组数据
  • ·第一行包括两个整数w和h(1<=w,h<=75),分别表示矩形板的宽度和长度
  • ·下面的h行,每行包括W个字符,表示矩形板上的游戏卡片分布情况:
  • ·使用X’表示这个地方有一个游戏卡片
  • ·使用空格表示这个地方没有游戏卡片
  • ·之后每行上包括4个整数:×1,y1,×2,y2(1<=x1,x2<=w,1<=y1,y2<=h)
  • ·给出两个卡片在矩形板上的位置
  • 注意:矩形板左上角的坐标是(1,1)输入保证这两个游戏卡片所处的位置是不相同的如果一行上有4个0,表示这组测试数据的结束
  • ·如果一行上给出W=h=0,那么表示所有的输入结束了

输出:

  • ·对每一个矩形板,输出一行“Board#n:",n是输入数据的编号
  • ·对每一组需要测试的游戏卡片输出一行.这一行的开头是“Pairm:”,这里m是测试卡片的编号(对每个矩形板编号都从1开始)
  • ·如果可以相连,找到连接这两个卡片的所有路径中包括线段数最少的路径,输出“k segments."
  • k是找到的最优路径中包括的线段的数目
  • ·如果不能相连,输出“impossible.”
  • ·每组数据之后输出一个空行

迷宫求解问题:

  • 自相似性表现在每走一步的探测方式相同,可以用递归方法求解
  • 通过枚举方式找到从起点到终点的路径,朝一个方向走下去:

·如果走不通,则换个方向走

  • >四个方向都走不通,则回到上一步的地方,换个方向走
  • >依次走下去,直到走到终点
dfed88eb0cce3e1475ef29bbe3fd0003.png
b9e4d7c07b8de84eae8020e45db51421.png

判断新位置(x,y)是否有效

·T1:(x,y)在边界之内

(x>-1)&&(x-1)&&(y

·T2:该位置没有游戏卡片并且未曾走过

((board[y][x]=="")&&(mark[y][x]==false))

·T3:已经到达终点

(x==end_x)&&(y==end_y)&&(board[y][x]=='X")

综上,(x,y)有效的条件是T1&&(T2||T3)

3dccaa087ec9d54bf7c41ced20eeb672.png
#include #include #define MAXIN 75char board[MAXIN+2J[MAXIN+2];/定义矩形板int minstep,w,h,to[4][2]={0,1},{1,0},{0-1},{-1,0};//定义方向bool mark[MAXIN+2][MAXIN+2];//定义标记数组void Search(int now_x,int now_y,int end_x,int end_y,int step,int f{ if(step>minstep)return;//当前路径数大于minstep,返回>优化策略 if(now_x==end_x&&now_y==end_y){ //到达终点 if(minstep>step)//更新最小路径数 minstep=step; return; } for(int i=0;i<4;i++){ //枚举下一步的方向 int x=now_x+to][0];/得到新的位置 int y=now_y+to[i][1]; if((x>-1)&&(x-1)&&(y0){ //读入起点和终点 count++;minstep=100000;//初始化minstep为一个很大的值 memset(mark,false,sizeof(mark)); //递归搜索 Search(begin_x,begin_y,end_x,end_y,0,-1); //输出结果 if(minstep<100000)printf("Pair%d:%d segments.In",count,minstep); else printf("Pair%d:impossible.",count); } printf(""); }return 0;}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值