NOIP 2002 马拦过河卒 BFS+递推

Description :

如图,A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。

同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为方马的控制点。例如上图C点上的马可以控制9个点(图中的P1,P2...P8和C)。卒不能通过对方的控制点。

棋盘用坐标表示,A点(0,0)、B点(n, m)(n,m为不超过20的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定:C≠A,同时C≠B)。现在要求你计算出卒从A点能够到达B点的路 径的条数。

Input

B点的坐标(n,m)以及对方马的坐标(X,Y) {不用判错}

Output

一个整数(路径的条数)。

Sample Input

6 6 3 2

Sample Output

17

本题要求的是方案数  一般的想法是直接广搜  每到终点一次ans+1  然而这样需要耗费大量时间

经过仔细分析题目发现 :以为卒只能向右或向下 所以每个能到达的点的ans值都只和它左边和上面那个

点有关 所以能得到 ans[x][y]=ans[x-1][y]+ans[x][y-1]这样的递推公式

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node{
  int x,y;
};
int fx[2][2]={1,0,0,1};
int mfx[8][2]={-2,-1,-2,1,2,-1,2,1,1,2,-1,2,1,-2,-1,-2};
long long vis[30][30];
int m,n,ex,ey;
void init()  //初始化
{
    for(int i=0;i<30;i++)
        for(int j=0;j<30;j++)
        vis[i][j]=0;
    return;
}
long long pd(int a,int b)
{
    if(a<0||b<0)
        return 0;
    if(vis[a][b]==-1)
        return 0;
    return vis[a][b];
}
long long bfs()
{
    int i;
    queue<node>q;
    node now;
    int tx,ty;
    for(i=0;i<8;i++)  //马控制的区域
    {
        tx=m+mfx[i][0];
        ty=n+mfx[i][1];
        if(tx<0||ty<0)
            continue;
        vis[tx][ty]=-1;
    }
    vis[m][n]=-1;
    q.push((node){0,0});
    vis[0][0]=1;
    while(!q.empty())
    {
        now=q.front();
   //     cout<<now.x<<' '<<now.y<<' '<<vis[now.x][now.y]<<endl;
        q.pop();
        for(i=0;i<=1;i++) //两种走法
        {
            tx=now.x+fx[i][0];
            ty=now.y+fx[i][1];
            if(vis[tx][ty]!=0||tx>ex||ty>ey)     //不走重复的路(剪枝) ||  超过终点了 不能返回  所也不可能(剪枝)
                continue;
            vis[tx][ty]=pd(tx-1,ty)+pd(tx,ty-1);   //递推 (前值的下标小于0或 被马控制 则返回的值是0)
            q.push((node){tx,ty});
        }
    }
    return vis[ex][ey];
}
int main()
{
    scanf("%d%d%d%d",&ex,&ey,&m,&n);
        init();
        printf("%lld\n",bfs());
    return 0;
}
时间: 2024-08-03 14:12:52

NOIP 2002 马拦过河卒 BFS+递推的相关文章

NOIP 马拦过河卒

描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. 棋盘用坐标表示,A点(0, 0).B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的.现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步. 格式 输入格式 一行四个数据,分别表示B点坐标和马的坐标. 输出格式 一个数据,表示所有的

马拦过河卒心得体会

题目棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过河卒". 棋盘用坐标表示,A点(0, 0).B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的.现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步. 输入一行四个数据,分别表示B点坐标和马的坐标.(保证所有的数据有解) 输出一个数据

【回溯法】马拦过河卒

问题 I: [回溯法]马拦过河卒 时间限制: 1 Sec  内存限制: 128 MB提交: 43  解决: 13[提交][状态][讨论版] 题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. 棋盘用坐标表示,A点(0, 0).B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的.现在要求你计算出卒从A点能够到达B点的路径的条数

Vijos 1121 马拦过河卒

首先要看清题目,卒只能向右或者向下走.而不是四周转.这样的话就无解了. 定义f[i][j],表示走到(i,j)这个点时的总步数.这样就写出了一个递推公式f[i][j]=f[i-1]+f[i][j-1].因为卒是从(0,0)出发,所以f[0][0]=1,因为 f[i][j]只能从前一个状态转移过来.所以在转移前需要加特判即(i-1,j)和(i,j-1)两点不是马所控制的点.所以在递推之前还应有一个预处理.来处理马所能控制的点,预处理很好写.剩下的没有什么了.输出目标节点的 f 值即可. 代码: #

【动态规划】Vijos P1121 马拦过河卒

题目链接: https://vijos.org/p/1616 题目大意: 卒从(0,0)走到(n,m),只能向下或向右,不能被马一步碰到或走到马,有几种走法. 题目思路: [动态规划] 把马控制的地方全部标记,接下来DP,f[i][j]=f[i-1][j]+f[i][j-1]; 1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #inc

递推问题之马踏过河卒问题

problem 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过河卒". 棋盘用坐标表示,A点(0, 0).B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的.现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步. 输入描述 Input Description 一行四个数据,分别表示B

SDUT 1265-马拦过河卒(DFS)

马拦过河卒 Time Limit: 3000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过河卒".棋盘用坐标表示,A点(0,0).B点(n,m)(n,m为不超过15的整数),同样马的位置坐标是需要给出的.现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固

AC日记——过河卒 洛谷 1002

题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. 棋盘用坐标表示,A点(0, 0).B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的. 现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步. 输入输出格式 输入格式: 一行四个数据,分别表示B点坐标和马的坐标. 输出格式: 一

递推2--过河卒(Noip2002)

递推2--过河卒(Noip2002) 一.心得 写出递推公式就OK了,具体编程还是很简单的 二.题目及分析 过河卒(NOIp2002) [问题描述] 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过河卒". 棋盘用坐标表示,A点(0, 0).B点(n, m),(n, m为不超过20的整数),同样马的位置坐标是需要给出的.C≠A且C≠B.现在要求你计算出卒从