NOIP2002-----马拦过河卒【经典搜索】

来源:互联网 发布:淘宝上买印度仿制药 编辑:程序博客网 时间:2024/06/07 10:55

马拦过河卒


题目描述

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

棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入

第1行:4个数据,分别表示B点坐标和马的坐标。

输出

第1行:1个数据,表示所有的路径条数。

样例输入

6 6 3 3

样例输出

6


此题为经典搜索题,使用深度优先搜索与广(宽)度优先搜索均可解题。此处作者使用深搜。

初步分析题目可得

卒行走的规则:可以向下、或者向右
该马所在的点所有跳跃一步可达的点称为对方马的控制点。

得到这两点以后,做题就会更轻松。
继续分析可得:

卒不会走重复的路,所以不需要判定
马的控制点可以预处理


程序框架

一:基本变量

1:坐标(目的地,马)
2:方向变量(马有8个方向,卒有2个)
3:计数器(计方案)
4:地图(存马的控制点)
5:……

二:程序框架

int main()(主程序框架)

1:读数据(坐标)
2:预处理(马的控制点)
3:判断边界(控制点)
4:深搜
5:输出
6:return

void dfs()(深搜框架)

1: 判断到达
2:尝试每个方向
3:判断越界或控制点
4:继续搜索


附代码一份

#include<cstdio>#include<cstring>bool chess[25][25];int Bx,By,Hx,Hy,HORSE[8][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}},F[3][2]={{1,0},{0,1}},tot;//B点坐标,马坐标,马的除本身的8个控制点,向量,答案 void flag(int x,int y) //深度优先搜索 {    if(x==Bx && y==By) //当前位置是B点     {        tot++;        return;    }    for(int i=0;i<2;i++)    {        int nx=x+F[i][0],ny=y+F[i][1]; //当前坐标         if(nx<0 || nx>Bx || ny<0 || ny>By || chess[nx][ny]) continue; //越界或是控制点         flag(nx,ny); //新一轮搜索     }}int main(){    scanf("%d%d%d%d",&Bx,&By,&Hx,&Hy);    chess[Hx][Hy]=true; //马本身     for(int i=0;i<8;i++) //其余8个控制点     {        int nx=Hx+HORSE[i][0],ny=Hy+HORSE[i][1];        if(nx<0 || nx>=Bx || ny<0 || ny>=By) continue;        chess[nx][ny]=true;    }    flag(0,0);//搜索    printf("%d\n",tot);    return 0;}/*    Language: C++    Result: 正确    Time:788 ms    Memory:1028 kb*/

IN THE END

前面也说过了,此题可以使用广搜。但是广搜使用起来比较麻烦,所以基本都是使用深搜。有兴趣可以自己思考实践,再跟上方答案对拍一下,看看它们各自的优缺点。在此就不提供了(其实没有找到)

原创粉丝点击