【回溯法】马拦过河卒

问题 I: 【回溯法】马拦过河卒

时间限制: 1 Sec  内存限制: 128 MB
提交: 43  解决: 13
[提交][状态][讨论版]

题目描述

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

输入

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

输出

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

样例输入

6 6 3 3

样例输出

6

upc上好像测试数据有问题,写的是到20,别的网站都是到15,到二十回溯法肯定会超时啊,别的做的是不是都是用动态规划递推做的。去别的网站提交AC。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3
 4 using namespace std;
 5
 6 int n,m;
 7 int c=0;
 8 int horse_x,horse_y;
 9 int a[25][25]={0};//值为0可以走,为1不可走
10 int cou[25][25]={0};//记录到这一坐标的所有的路径条数
11
12 void horse_location(){
13     int x[8]={-2,-1,1,2,2,1,-1,-2};
14     int y[8]={1,2,2,1,-1,-2,-2,-1};
15     a[horse_x+1][horse_y+1]=1;
16     for(int i=0;i<8;i++){
17         int new_x=horse_x+x[i]+1;
18         int new_y=horse_y+y[i]+1;
19         if(new_x>=1&&new_y<=n+1&&new_y>=1&&new_y<=m+1){
20             a[horse_x+x[i]+1][horse_y+y[i]+1]=1;
21         }
22     }
23 }
24
25 void backtrack(int x,int y){
26     int xx[2]={0,1};
27     int yy[2]={1,0};
28     if(x==n+1&&y==m+1){
29         c++;
30         return ;
31     }
32     for(int i=0;i<2;i++){
33         if(a[x+xx[i]][y+yy[i]]==0){
34             backtrack(x+xx[i],y+yy[i]);
35         }
36     }
37 }
38
39 int main()
40 {
41     scanf("%d %d %d %d",&n,&m,&horse_x,&horse_y);
42     horse_location();
43     for(int i=1;i<=m+2;i++){
44         a[n+2][i]=1;
45     }
46     for(int i=1;i<=n+2;i++){
47         a[i][m+2]=1;
48     }
49     backtrack(1,1);
50     printf("%d",c);
51     return 0;
52 }

				
时间: 2024-10-21 23:16:20

【回溯法】马拦过河卒的相关文章

马拦过河卒心得体会

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

NOIP 马拦过河卒

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

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点的路 径的

【动态规划】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

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 值即可. 代码: #

SDUT 1265-马拦过河卒(DFS)

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

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

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

【水】noip2002普及 过河卒

这题似乎是当年的马拦过河卒,好久的回忆啊... 过河卒 来源 NOIP2002普及组 题目描述 如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点.例 如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C).卒不能通过对方马的控制点. 棋盘用坐标表示,A 点(0,0).B 点(n,m)(n,m 为不超过 25 的整数,并由键盘输入),同样马的

洛谷P1002 过河卒

看到就顺便做了 NOIP2002普及组.那个年代还没有int64,不得不用高精算,然而现在一个long long就解决了.感受到了时代的进步呢. 题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. 棋盘用坐标表示,A点(0, 0).B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的. 现在要求你计算出卒从A点能够到达B点的路