ACM小组的古怪象棋
Problem Description
ACM小组的Samsara和Staginner对中国象棋特别感兴趣,尤其对马(可能是因为这个棋子的走法比较多吧)的使用进行深入研究。今天他们又在 构思一个古怪的棋局:假如Samsara只有一个马了,而Staginner又只剩下一个将,两个棋子都在棋盘的一边,马不能出这一半棋盘的范围,另外这 一半棋盘的大小很奇特(n行m列)。Samsara想知道他的马最少需要跳几次才能吃掉Staginner的将(我们假定其不会移动)。当然这个光荣的任 务就落在了会编程的你的身上了。
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
解题思路:
这么水的。。直接BFS就好了。
Code:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=20+5;
int vis[maxn][maxn];
int n,m;
int dx[]= {-2,-1,1,2,2,1,-1,-2};
int dy[]= {1,2,2,1,-1,-2,-2,-1};
struct Node
{
int x,y,step;
};
queue<Node> Q;
bool check(int x,int y)
{
if(x<0||x>=n||y<0||y>=m)
return false;
if(vis[x][y])
return false;
return true;
}
int BFS(int x1,int y1,int x2,int y2)
{
vis[x1][y1]=1;
Q.push((Node)
{
x1,y1,0
});
while(!Q.empty())
{
Node &u=Q.front();
//cout<<u.x<<' '<<u.y<<' '<<u.step<<endl;
if(u.x==x2&&u.y==y2)
return u.step;
Q.pop();
for(int i=0; i<8; i++)
{
int x=u.x+dx[i];
int y=u.y+dy[i];
if(check(x,y))
{
vis[x][y]=1;
Q.push(Node{x,y,u.step+1});
}
}
}
return -1;
}
int main()
{
int x1,y1,x2,y2;
while(scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&x2,&y2)!=EOF)
{
mem(vis,0);
int ans=BFS(x2,y2,x1,y1);
printf("%d\n",ans);
}
return 0;
}