zoukankan      html  css  js  c++  java
  • 算法与数据结构---过河卒-搜索(递归)写法常见易错点

    算法与数据结构---过河卒-搜索(递归)写法常见易错点

    一、总结

    一句话总结:

    f[i][j]=f[i-1][j]+f[i][j-1]这样的递推表达式,取数之前一定要保证数是存在的

    1、表示马的控制点如何表示?

    int hx[9]={0,-2,-1,1,2,2,1,-1,-2};
    int hy[9]={0,1,2,2,1,-1,-2,-2,-1};

    2、边界条件不清晰易出错?

    A、横轴f[i][0]=1(1<=i<=bx)和纵轴f[0][i]=1(1<=i<=by)是边界点,
    B、f[i][by]和f[bx][i]并不是边界点
    C、f[i][0]=1和f[0][i]=1做边界点会出错,因为当马的位置如果是(4,0),那么(5,0)的位置本来是去不了的,

    3、递归一般是由终止条件到达初始条件,比如过河卒?

    那么递归的关系式应该是f[i][j]=f[i-1][j]+f[i][j-1],而不是f[i][j]=f[i+1][j]+f[i][j+1]

    4、这题(过河卒)的数据量是大于int的,所以定义缓存数组f的时候要用long long?

    long long f[25][25];这题的数据量是大于int的,所以要用long long

    5、这题(过河卒)的数据量是大于int的,所以递归函数的返回值要用long long,而不能是int?

    int find(int x,int y){} 这样就是错的
    //递归函数返回值的问题
    int find(int x,int y){
        if(f[x][y]!=-1) return f[x][y];
        else{
            return f[x][y]=find(x-1,y)+find(x,y-1);
        }
    }

    6、如下初始化f[i][0]和f[0][i]会造成什么问题?

    如果有马在中间,比如(4,0),4后面的点本来是达不到的,但是如下初始化之后,是可以达到的,这样就出错了

    |||-begin

    初始状态:
    马控制的点为0
    f[0][0]=0
    f[i][0]=1 (1<=i<=bx)
    f[0][i]=1 (1<=i<=by)
    //初始化f数组
    f[0][0]=0;
    for(int i=1;i<=bx;i++) f[i][0]=1;
    for(int i=1;i<=by;i++) f[0][i]=1;

    |||-end

    7、f[i][j]=f[i-1][j]+f[i][j-1]这样的递推表达式,无论是做递归,还是做递推,要注意什么?

    要保证i和j大于等于1,小于1的情况要单独分析,取数之前一定要保证数是存在的

    二、过河卒-递归写法常见易错点

    博客对应课程的视频位置:

    1、题目描述

     

    题目位置

    P1002 过河卒 - 洛谷
    https://www.luogu.com.cn/problem/P1002

     

    2、代码

     1 /*
     2 
     3 卒子可以向下走和向右走
     4 
     5 如果没有这个马,搜索应该怎么做
     6 
     7 递归:
     8 递归的终止条件:起点
     9 递归的递推表达式:卒子可以向下走和向右走
    10 (f[i][j]=f[i-1][j]+f[i][j-1])
    11 递归的返回值:路径条数
    12 
    13 
    14 如果有马的情况
    15 递归的终止条件:起点或者马控制的区域
    16 
    17 
    18 A是A点 , B是B点, M是马的位置, X是被马拦着不能走的点
    19 A 0 0 0 0 0 0
    20 0 0 X 0 X 0 0
    21 0 X 0 0 0 X 0
    22 0 0 0 M 0 0 0
    23 0 X 0 0 0 X 0
    24 0 0 X 0 X 0 0
    25 0 0 0 0 0 0 B
    26 其中每个点的值代表的是当前这个点会有几条路径用过这个点
    27 (路径指的是从A到B的路径)
    28 
    29 1 1 1 1 1 1 1
    30 1 2 X 1 X 1 2
    31 1 X 0 1 1 X 2
    32 1 1 1 M 1 1 3
    33 1 X 1 1 0 X 3
    34 1 1 X 1 X 0 3
    35 1 2 2 3 3 3 6
    36 
    37 
    38 这里初始化的时候能直接初始化i=0和j=0对应的两条线么
    39 不能,因为如果这样初始化后,当马的位置如果是(4,0),
    40 那么(5,0)的位置本来是去不了的,
    41 但是这样初始化却会初始化为1
    42 
    43 
    44 */
    45 #include <iostream>
    46 #include <cstring>
    47 using namespace std;
    48 int hx[9]={0,-2,-1,1,2,2,1,-1,-2};
    49 int hy[9]={0,1,2,2,1,-1,-2,-2,-1};
    50 long long f[25][25];
    51 //递归函数返回值的问题
    52 long long find(int x,int y){
    53     if(f[x][y]!=-1) return f[x][y];
    54     else{
    55         if(x-1>=0&&y-1>=0) return f[x][y]=find(x-1,y)+find(x,y-1);
    56         else if(x-1>=0) return f[x][y]=find(x-1,y);
    57         else if(y-1>=0) return f[x][y]=find(x,y-1);
    58         else return 0;   
    59     }
    60 }
    61 
    62 int main(){
    63     int bx,by,mx,my;
    64     cin>>bx>>by>>mx>>my;
    65     //初始化f数组
    66     memset(f,-1,sizeof(f));
    67     f[0][0]=1;
    68     //将马控制得到的位置初始化到f数组
    69     for(int i=0;i<=8;i++){
    70         //马的位置没出界
    71         int now_x=mx+hx[i];
    72         int now_y=my+hy[i];
    73         if(now_x>=0&&now_x<=bx&&now_y>=0&&now_y<=by){
    74             f[now_x][now_y]=0; 
    75         }
    76     }
    77 
    78     cout<<find(bx,by)<<endl;
    79     return 0;
    80 }
     
  • 相关阅读:
    JS: Promise
    JS: 数据结构与算法之栈
    JS: 数组乱序
    JS: 数组扁平化
    JS:函数柯里化
    JS: 防抖节流
    JS:事件委托
    理解Node.js(译文)
    Javascript闭包入门(译文)
    你真的懂ajax吗?
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/13107411.html
Copyright © 2011-2022 走看看