当前位置:首页 > 题解目录 > 正文内容

【题解】马拦过河卒

亿万年的星光5年前 (2021-03-20)题解目录1990

【题目描述】

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

【输入描述】

一行四个数据,分别表示B点坐标和马的坐标。(保证所有的数据有解)

【输出描述】

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

【样例输入】

6 6 3 3

【样例输出】

6

【题目分析】

  • 马走日的改编版,需求遍历整个棋盘,但是这次改成了”卒“遍历棋盘(到达目的地)。

  • 卒只能向下或者向右,绝对不能走回头路,不然就可能有无数条路径了,可以用数组表示。

  • 马能走的路径至多有8个(理想情况下),可以通过数组把这8个点分别表示出来,这样给定任何一个马的坐标都可以表示其余方位。


  • 如果马在边界点上,有些坐标是不需要考虑的

  • 一定注意是”卒“躲过”马“的袭击,到达目标点,不是”马“怎么走才能吃掉”卒“

  • 题目保证有解,所以决定不存在什么”卒的起始位置就是马能跳的点“类似情况

  • DFS深搜加上判断条件即可,注意m和n的最大是15

  • 本题使用框架二,用flag数组表示马能走的点。

  • int Search(int k)
     {
       if  (到目的地) 输出解;
       else
        for (i=1;i<=算符种数;i++)
         if  (满足条件) 
           {
            保存结果;
                         Search(k+1);
            恢复:保存结果之前的状态{回溯一步}
           }
     }


   


【参考答案】


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int x,y,hx,hy; //定义B点坐标和马的坐标
int dx[2]= {0,1}; //卒的x变化
int dy[2]= {1,0}; //卒的y变化
bool flag[16][16]; //标记数组,用来标记哪些点能走或不能走
int sum; //定义总路径条数
void changeFlag(int x,int y) { //马能走的所有路径都封死,不让卒走
	flag[x][y]=1;
	flag[x-1][y-2]=1;
	flag[x-2][y-1]=1;
	flag[x-2][y+1]=1;
	flag[x-1][y+2]=1;
	flag[x+1][y-2]=1;
	flag[x+2][y-1]=1;
	flag[x+2][y+1]=1;
	flag[x+1][y+2]=1;
	//此处有个小问题,就是如果马的坐标在左边界的时候,数组有可能出现flag[-1][0]这类越界问题。但是,题目保证有解,所以在这个地方没有额外考虑
}
//使用框架二
void dfs(int sx,int sy) {
	if(sx==x && sy==y) {
		sum++;  //到达b点就累加1
		return;
	}
	for(int i=0; i<2; i++) { //卒只有两走法(下,右)
		int fx=sx+dx[i]; //当前卒的某一方向的x坐标
		int fy=sy+dy[i]; //当前卒的某一方向的y坐标
		if(flag[fx][fy]==0 && fx<=x && fy<=y) { 
		//如果当前这个点没有在马的目标点上,而且没有超过目标点x,y 
			flag[fx][fy]=1; //将当前点变为1,表示此点已经走过了 
			dfs(fx,fy); //继续遍历下一个点 
			flag[fx][fy]=0; //回溯一步 
		}
	}

}
int main() {
	cin>>x>>y>>hx>>hy;
	changeFlag(hx,hy); //把马走的路径封死
	dfs(0,0); //从0,0开始遍历,注意,是 卒 的遍历,不是马
	cout<<sum<<endl;
	return 0;
}



    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    分享给朋友:

    相关文章

    家庭作业

    题目描述老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为10,要求在6天内交,那么要想拿到这10学分,就...

    【题解】幸运儿

    【题目描述】n 个人围成一圈, 并依次编号1~n,从编号为1 的人开始,按顺时针方向每隔一人选出一个,当一圈结束之后,剩下的人重新围成一圈,再次从编号1的人开始,如此循环直到剩下两人,这剩下的两人就是...

    【题解】日期排序

    【题目描述】有一些日期,日期格式为“MM/DD/YYYY”。编程将其按日期大小排列。【输入描述】无【输出描述】无【样例输入】15/12/1999 10/21/2003 10/22/2003 02...

    【题解】链表操作

    【题目描述】给定一个N个数的数组,M次操作,每次操作为下列操作之一。求最后的数组。操作1:在第X个数之后插入一个数Y。操作2:删除第X个数。操作3:对区间[X,Y]进行排序。操作4:对区间[X,Y]进...

    【题解】BFS—迷宫问题(1)

    【题解】BFS—迷宫问题(1)

    【题目描述】一个5*5的矩阵,矩阵内用0,1显示。其中,0是路,表示这个点可以走,1是墙表示这个点不可以走。问,从给定的矩阵中从左上角到右下角最少需要走多少步?注:题目保证有解(不存在左上角和右下角为...

    【题解】校运会

    【题解】校运会

    【题目描述】校运会上,一共有N个参赛选手,已知N个选手的名字。然后老师告诉你M句话,话的内容是学生A与学生B在同一组里。如果学生A与学生B在同一组里,学生B与学生C也在同一组里,就说明学生A与学生C在...