• 算法与数据结构---8.1、过河卒-搜索解法


    算法与数据结构---8.1、过河卒-搜索解法

    一、总结

    一句话总结:

    过河卒搜索的解法可以先思考没有马的简单情况,有马的情况,只是递归的终止条件从起点变成了起点或者马控制的区域
    #include <iostream>
    #include <cstring>
    using namespace std;
    int hx[9]={0,-2,-1,1,2,2,1,-1,-2};
    int hy[9]={0,1,2,2,1,-1,-2,-2,-1};
    long long f[25][25];
    long long find(int x,int y){
        //如果缓存里面有,就从缓存里面拿
        //否则计算结果存入缓存
        if(f[x][y]!=-1) return f[x][y];
        else{
            //f[i][j]=f[i-1][j]+f[i][j-1]
            if(x-1>=0&&y-1>=0) return f[x][y]=find(x-1,y)+find(x,y-1);
            else if(x-1>=0) return f[x][y]=find(x-1,y);
            else if(y-1>=0) return f[x][y]=find(x,y-1);
            else return f[x][y]=0;
        }
    }
    
    int main(){
        int bx,by,mx,my;
        cin>>bx>>by>>mx>>my;
        memset(f,-1,sizeof(f));
        f[0][0]=1;
    
        //将马控制的点加入到f数组
        for(int i=0;i<=8;i++){
            int now_x=mx+hx[i];
            int now_y=my+hy[i];
            if(now_x>=0&&now_y>=0){
                f[now_x][now_y]=0;
            }
        }
    
        cout<<find(bx,by)<<endl;
        return 0;
    }

    1、过河卒的搜索解法的注意点?

    1、本题(过河卒)的路径条数是超过int的,所以要用long long
    2、使用递推表达式f[i][j]=f[i-1][j]+f[i][j-1]时,因为有i-1、j-1,所以要考虑i、j是否大于1的情况
    3、初始化的时候,不能直接初始化i=0和j=0对应的两条线,因为当马的控制点在这两条线上时,控制点后的点是达不到的

    二、过河卒

    1、题目描述

     

    /*
    
    题目位置:
    P1002 过河卒 - 洛谷
    https://www.luogu.com.cn/problem/P1002
    
    */
    
    /*
    样例输入:6 6 3 3
    样例输出:6
    
    
    b点是(6,6),马的坐标是(3,3)
    
    A是A点 , B是B点, M是马的位置, X是被马拦着不能走的点
    A 0 0 0 0 0 0
    0 0 X 0 X 0 0
    0 X 0 0 0 X 0
    0 0 0 M 0 0 0
    0 X 0 0 0 X 0
    0 0 X 0 X 0 0
    0 0 0 0 0 0 B
    其中每个点的值代表的是当前这个点会有几条路径用过这个点
    (路径指的是从A到B的路径)
    
    1 1 1 1 1 1 1
    1 2 X 1 X 1 2
    1 X 0 1 1 X 2
    1 1 1 M 1 1 3
    1 X 1 1 0 X 3
    1 1 X 1 X 0 3
    1 2 2 3 3 3 6
    
    
    */
     

    2、搜索解法

    博客对应课程的视频位置:8.1、过河卒-搜索解法
    https://www.fanrenyi.com/video/27/288

     1 /*
     2 
     3 递推表达式:
     4 卒子可以向下走和向右走
     5 如果设f[i][j]表示走到(i,j)点的路径总数
     6 对应的走到f[i][j]只能从上边来或者从左边来
     7 f[i][j]=f[i-1][j]+f[i][j-1]
     8 
     9 
    10 简单的思考:
    11 如果没有这个马,搜索应该怎么做
    12 
    13 递归:
    14 递归的终止条件:起点
    15 递归的递推表达式:f[i][j]=f[i-1][j]+f[i][j-1]
    16 递归的返回值:路径条数
    17 
    18 初始值:f[0][0]=1
    19 
    20 如果有马的情况
    21 递归的终止条件:起点或者马控制的区域
    22 
    23 
    24 注意:
    25 1、本题的路径条数是超过int的,所以要用long long
    26 2、使用递推表达式f[i][j]=f[i-1][j]+f[i][j-1]时,
    27 因为有i-1、j-1,所以要考虑i、j是否大于1的情况
    28 3、初始化的时候,不能直接初始化i=0和j=0对应的两条线,
    29 因为当马的控制点在这两条线上时,控制点后的点是达不到的
    30 
    31 
    32 思考:
    33 1 1 1 1 1 1 1
    34 1 2 X 1 X 1 2
    35 1 X 0 1 1 X 2
    36 1 1 1 M 1 1 3
    37 1 X 1 1 0 X 3
    38 1 1 X 1 X 0 3
    39 1 2 2 3 3 3 6
    40 这里初始化的时候能直接初始化i=0和j=0对应的两条线么
    41 不能,因为如果这样初始化后,当马的位置如果是(4,0),
    42 那么(5,0)的位置本来是去不了的,
    43 但是这样初始化却会初始化为1
    44 
    45 
    46 */
    47 #include <iostream>
    48 #include <cstring>
    49 using namespace std;
    50 int hx[9]={0,-2,-1,1,2,2,1,-1,-2};
    51 int hy[9]={0,1,2,2,1,-1,-2,-2,-1};
    52 long long f[25][25];
    53 long long find(int x,int y){
    54     //如果缓存里面有,就从缓存里面拿
    55     //否则计算结果存入缓存
    56     if(f[x][y]!=-1) return f[x][y];
    57     else{
    58         //f[i][j]=f[i-1][j]+f[i][j-1]
    59         if(x-1>=0&&y-1>=0) return f[x][y]=find(x-1,y)+find(x,y-1);
    60         else if(x-1>=0) return f[x][y]=find(x-1,y);
    61         else if(y-1>=0) return f[x][y]=find(x,y-1);
    62         else return f[x][y]=0;
    63     }
    64 }
    65 
    66 int main(){
    67     int bx,by,mx,my;
    68     cin>>bx>>by>>mx>>my;
    69     memset(f,-1,sizeof(f));
    70     f[0][0]=1;
    71 
    72     //将马控制的点加入到f数组
    73     for(int i=0;i<=8;i++){
    74         int now_x=mx+hx[i];
    75         int now_y=my+hy[i];
    76         if(now_x>=0&&now_y>=0){
    77             f[now_x][now_y]=0;
    78         }
    79     }
    80 
    81     cout<<find(bx,by)<<endl;
    82     return 0;
    83 }
     
     
  • 相关阅读:
    后缀零
    vs2019 MFC的安装 解决 此项目需要 MFC 库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体系结构安装它们。
    矩形切割
    fsync: failed to connect to feed.openvas.org (89.146.224.58)
    How to Install GVM Trial With VMware Workstation Player/Pro
    GVM 21.04 (stable, initial release 20210416)
    gitlab 升级相关
    Adobe Reader XI 11.0.23 简体中文版
    gofileserver GO HTTP 文件下载服务器
    KVM 中安装 Windows 10 虚拟机、CentOS 8 虚拟机及快照操作
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/13080404.html
Copyright © 2020-2023  润新知