问题描述
Description
只有一个马了,又只剩下一个将,两个棋子都在棋盘的一边,马不能出这一半棋盘的范围,棋盘的大小(n行m列)。想知道他的马最少需要跳几次才能吃掉将(我们假定其不会移动)。
Input
每组数据一行,分别为六个用空格分隔开的正整数n,m,x1,y1,x2,y2分别代表棋盘的大小n,m,以及将的坐标和马的坐标。(1<=x1,x2<=n<=20,1<=y1,y2<=m<=20,将和马的坐标不相同)
Output
输出对应也有若干行,请输出最少的移动步数,如果不能吃掉将则输出“-1”(不包括引号)。
Sample Input
8 8 5 1 4 5
Sample Output
3
我的思路
本题特色: 马的行走方式 防止蹩脚 用了四个 if 解决
这题是学习BFS的基础题 类似于搜索迷宫 只是把棋子换成了马 跳转方式不一样 本题同样可以适用DP方法解决 所以 对于初学者 建议先学习BFS解法 再经过少量改动达到DP的方法 系统的学习ACM算法
[AC代码]
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
#include<cmath>
#define LL long long
#define fi first
#define se second
#define IO; std::ios::sync_with_stdio(false);std::cin.tie(0);
//降低输入输出时间
using namespace std;
const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-10;
const double PI = acos(-1);
/**********BFS模板**********/
const int maxn=100;
bool vst[maxn][maxn]; // 访问标记
int t[maxn][maxn];//存放最小层数
int dir[8][2]={{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{-1,2},{1,-2},{-1,-2}}; // 方向向量
int res;//结果层数
int n,m,xm,ym,xj,yj;//输入量
struct State // BFS 队列中的状态数据结构
{
int x,y; // 坐标位置
int Step_Counter; // 搜索步数统计器
};
State a[maxn];
bool CheckState(State s) // 约束条件检验
{
if(vst[s.x][s.y]==0 && s.x>=0 && s.x<n && s.y>=0 && s.y<m) // 满足条件
return 1;
else
return 0;
}
void bfs(State st)
{
memset(vst,0,sizeof(vst));
queue <State> q; // BFS 队列
State now,next; // 定义2 个状态,当前和下一个
st.Step_Counter=0; // 计数器清零
q.push(st); // 入队
vst[st.x][st.y]=1; // 访问标记
while(!q.empty())
{
now=q.front(); // 取队首元素进行扩展
if(now.x==xj&&now.y==yj) // 出现目标态,此时为Step_Counter 的最小值,可以退出即可
{
res=now.Step_Counter;// 结果
return;
}
for(int i=0;i<8;i++)
{
next.x=now.x+dir[i][0]; // 按照规则生成下一个状态
next.y=now.y+dir[i][1];
next.Step_Counter=now.Step_Counter+1; // 计数器加1
//防止蹩脚
if(dir[i][0]==2 && now.x+1==xj && now.y==yj ) continue;
if(dir[i][0]==-2 && now.x-1==xj && now.y==yj ) continue;
if(dir[i][1]==2 && now.x==xj && now.y+1==yj) continue;
if(dir[i][1]==-2 && now.x==xj && now.y-1==yj) continue;
if(CheckState(next)) // 如果状态满足约束条件则入队
{
t[next.x][next.y]=min(t[next.x][next.y],t[now.x][now.y]+1);
q.push(next);
vst[next.x][next.y]=1; //访问标记
}
}
q.pop(); // 队首元素出队
}
return;
}
void csh()
{
for(int i=0;i<100;i++)
for(int j=0;j<100;j++)
t[i][j]=inf;
}
int main()
{
IO;
while(cin>>n>>m>>xj>>yj>>xm>>ym)
{
csh();
xj--,yj--,xm--,ym--;
t[xm][ym]=0;
State st;
st.x=xm;st.y=ym;
bfs(st);
if (t[xj][yj]==inf) cout<<"-1"<<endl;
else cout<<res<<endl;//或者cout<<t[xj][yj]<<endl;
}
return 0;
}