试题描述
|
我们知道在中国象棋的棋盘上,马走日字行的(如下图所示),现在有一个 N*M 的方格棋盘,给定两个点的坐标 A(a1,b1) 和 B(a2,b2),问按照马走日字的规则,再附加一条马只能望右跳,问能否实现从 A 点走到 B 点。 |
输入
|
两行,第一行包含两个数 N 和 M,第二行包括四个数分别为 a1,b1,a2 和 b2。各行的数两两之间用一个空格分隔。
|
输出
|
yes 或 no
|
输入示例
|
8 8
0 0 3 3 |
输出示例
|
yes
|
其他说明
|
数据范围:1 < N,M < 100, 0 <= a1,a2 <= M-1,0 <= b1,b2 <= N-1.
|
这是一道有趣的题。既可以用DFS,又可以用BFS。但事实上是,DFS很有可能超限,而BFS则不会。
1 #include <iostream> 2 3 using namespace std; 4 int n,m,a1,a2,b1,b2; 5 bool dfs(int x,int y) 6 { 7 if(x==a2 && y==b2) return 1; //到达目的地 8 if(y>=b2) return 0; //当前位置已经在目的地右边,而题目中又说只能向右走,所以不可能到达目的地 9 if(x+2<m && y+1<n) if(dfs(x+2,y+1)) return 1; //接下来分四种情况考虑,先判断边界,然后找路径 10 if(x+1<m && y+2<n) if(dfs(x+1,y+2)) return 1; 11 if(x-1>=0 && y+2<n) if(dfs(x-1,y+2)) return 1; 12 if(x-2>=0 && y+1<n) if(dfs(x-2,y+1)) return 1; 13 return 0; //无论如何找不到路径 14 } 15 int main() 16 { 17 scanf("%d%d",&m,&n); 18 scanf("%d%d%d%d",&a1,&b1,&a2,&b2); 19 if(dfs(a1,b1)) printf("yes"); 20 else printf("no"); 21 //system("pause"); 22 return 0; 23 }
1 #include<iostream> 2 #include<queue> //BFS用队列 3 using namespace std; 4 queue<int>x; 5 queue<int>y; 6 int m,n,stx,sty,edx,edy; //start end 7 int bfs() 8 { 9 if(x.empty()||y.empty()) {cout<<"no";exit(0);} //到边界,退出 10 int x1=x.front(); //取队头 11 int y1=y.front(); 12 x.pop(); //删对头 13 y.pop(); 14 if(x1==edx && y1==edy) {cout<<"yes";exit(0);} //到达目的地 15 if(x1<n && x1>=0 && y1<m && y1>=0) //判断边界,如果都没出界 16 { 17 x.push(x1+2);y.push(y1-1); //四种情况同时考虑 18 x.push(x1+2);y.push(y1+1); 19 x.push(x1+1);y.push(y1+2); 20 x.push(x1+1);y.push(y1-2); 21 } 22 bfs(); 23 } 24 int main() 25 { 26 cin>>n>>m>>stx>>sty>>edx>>edy; 27 x.push(stx); 28 y.push(sty); 29 bfs(); 30 //system("pause"); 31 return 0; 32 }