首页 > 其他分享 >动态规划和层次遍历 —— [NOIP2002 普及组] 过河卒

动态规划和层次遍历 —— [NOIP2002 普及组] 过河卒

时间:2024-04-08 18:29:17浏览次数:20  
标签:遍历 过河 NOIP2002 int len 20 1LL 坐标 table

题目如下:

[NOIP2002 普及组] 过河卒

题目描述

棋盘上 A A A 点有一个过河卒,需要走到目标 B B B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C C C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示, A A A 点 ( 0 , 0 ) (0, 0) (0,0)、 B B B 点 ( n , m ) (n, m) (n,m),同样马的位置坐标是需要给出的。

现在要求你计算出卒从 A A A 点能够到达 B B B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入格式

一行四个正整数,分别表示 B B B 点坐标和马的坐标。

输出格式

一个整数,表示所有的路径条数。

样例 #1

样例输入 #1

6 6 3 3

样例输出 #1

6

提示

对于 100 % 100 \% 100% 的数据, 1 ≤ n , m ≤ 20 1 \le n, m \le 20 1≤n,m≤20, 0 ≤ 0 \le 0≤ 马的坐标 ≤ 20 \le 20 ≤20。

【题目来源】

NOIP 2002 普及组第四题

思路:根据 B B B点的位置确认棋盘table的大小,table[ i i i][ j j j]存储卒走到( i i i, j j j)的走法数量。显然table[ 0 0 0][ 0 0 0]=1。
对于马和马能走到的地方的坐标对应的table位置的值,置为-1.
如果要走到( i i i, j j j),则只能从( i − 1 i-1 i−1, j j j)或( i i i, j − 1 j-1 j−1)走过去,故写出状态转移方程:

t a b l e [ i ] [ j ] = t a b l e [ i − 1 ] [ j ] + t a b l e [ i ] [ j − 1 ] table[i][j] = table[i-1][j]+table[i][j-1] table[i][j]=table[i−1][j]+table[i][j−1]

如果等号右边table下标超出范围,则结果为0。
我们自然可以每次运算时遍历整个table二维数组,但更简单的方式是层次遍历,如图所示:
在这里插入图片描述
这是一种层次化遍历,节省了时间开销。
注意数据范围:最坏的情况二维数组存储的数字会超过int范围,故开int64防爆。
完整代码如下:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int m,n,p,q;//B坐标和马坐标

int dx[8] = {1,2,-1,-2,1,2,-1,-2};
int dy[8] = {2,1,-2,-1,-2,-1,2,1};

bool check(int x,int y){//判断是否在棋盘内
    return x>=0&&x<=m&&y>=0&&y<=n;
}

int main(){
    cin >> m >> n >> p >> q;
    vector<vector<ll>> table(m+1,vector<ll>(n+1,0LL));
    table[p][q] = -1LL;
    for(int i=0;i<8;i++){
        int x = p+dx[i];
        int y = q+dy[i];
        if(check(x,y)){
            table[x][y] = -1LL;
        }
    }
    int maxlen = m+n+1;
    table[0][0] = 1LL;
    for(int len=1;len<=maxlen;len++){
        for(int i=0;i<=len;i++){
            if(check(i,len-i) && table[i][len-i]!=-1LL){
                if(check(i-1,len-i) && table[i-1][len-i]!=-1LL){
                    table[i][len-i] += table[i-1][len-i];
                }
                if(check(i,len-i-1) && table[i][len-i-1]!=-1LL){
                    table[i][len-i] += table[i][len-i-1];
                }
            }
        }
    }
    cout << table[m][n] << endl;    
}

感谢你能看到这里。]

标签:遍历,过河,NOIP2002,int,len,20,1LL,坐标,table
From: https://blog.csdn.net/q1557137513/article/details/137513563

相关文章

  • Oracle 递归遍历
    1、场景递归到第几层,例如递归到第2层   selectlevel,--层级wdj.*fromwip_discrete_jobs_vwdjwhere1=1startwithwdj.wip_entity_name='08363790'--递归开始connectbywdj.attribute3=priorwdj.wip_entity_nameandlevel<3; 2、一行数据出现两......
  • P1002 [NOIP2002 普及组] 过河卒
    题意:卒子过河,有个马,问安全到达终点的路径有多少条。起点在0,0。每一步可以往右或者往下。思路:处理出马的看守点,然后暴力。。看了一下暴力会TLE。400^2.直接dp转移即可。总结:不知道这个还要开longlong,哎。!voidsolve(){pair<int,int>destination;vector<pair<int......
  • Elasticsearch,使用scroll实现遍历(分页)查询
    为什么要使用scroll查询在使用es中,当某个index存贮的数据超过10000时,只能查询到10000的数据。因为index.max_result_window默认值是10000。并且使用游标查询可以在一次查询中获取大量文档,并且保持查询快照状态,允许用户多次检索数据而不影响其他并发请求。scroll查......
  • 二叉树的非递归遍历
    感谢b站up主优雅的代码:https://space.bilibili.com/95715842二叉树的非递归遍历非递归的先序遍历思想:利用栈先进后出的性质。将根节点入栈,(根节点出栈的同时先拉右子树入栈,之后拉左子树入栈;左子树出栈的同时先拉其右子树入栈);依次继续。voidpreOrder(TreeNode*root){......
  • bs4的使用 遍历文档树
     bs4的使用#遍历文档树#搜索文档树(5种过滤规则)#limit和recursive参数importrequests#pip3installbeautifulsoup4解析html和xml,修改html和xmlfrombs4importBeautifulSoup#res=requests.get('https://www.autohome.com.cn/news/1/#liststart')##withop......
  • 图的遍历试题解析
    一、单项选择题01.下列关于广度优先算法的说法中,正确的是(A ).Ⅰ.当各边的权值相等时,广度优先算法可以解决单源最短路径问题Ⅱ.当各边的权值不等时,广度优先算法可用来解决单源最短路径问题Ⅲ.广度优先遍历算法类似于树中的后序遍历算法Ⅳ.实现图的广度优先算法时,使用的......
  • 18天【代码随想录算法训练营34期】● 513.找树左下角的值 ● 112. 路径总和 113.路径
    513.找树左下角的值#Definitionforabinarytreenode.#classTreeNode:#def__init__(self,val=0,left=None,right=None):#self.val=val#self.left=left#self.right=rightclassSolution:deffindBottomLeftValue(self......
  • 二叉树-迭代遍历
    递归的实现是每次递归调用都把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候就从栈顶弹出上一次递归的各项参数。可利用栈实现二叉树的前中后序遍历。前序遍历前序遍历是中左右的顺序,整体过程就是逐次访问父节点,压入右孩子再压入左孩子,由于访问的节点和待......
  • 2.手写JavaScript广度和深度优先遍历二叉树
    一、核心思想:1.深度遍历:依靠栈先进后出的机制,分别设置返回结果的数组和栈数组,首先判断栈非空,对每个结点,将其出栈并把值push到结果数组,判断是否有右左孩子,分别将其加入栈中,循环执行上述操作。否则返回结果数组。2.广度遍历:依靠队列先进先出的机制,分别设置返回结果的数组和队......
  • 二叉树-递归遍历
    深度优先遍历先往深走,遇到叶子结点再往回走,分为前序遍历,中序遍历和后序遍历。方法有递归法和迭代法。前中后序遍历,指的是中间节点的遍历顺序。前序遍历:5412678中左右中序遍历:1425768左中右后序遍历:1247865左右中深度优先遍历可利用递归法或者迭代法实......