江湖是什么,对于在象棋界厮杀的QQ来说,江湖就是一个矩阵,他的目标,就是在江湖之中骑着马,从他的位置出发,走到终点。
当然,QQ的马也遵从中国象棋中的“马走日”的规则,而且在矩阵中,也会有一些障碍物,马不能跳到障碍物上;如果大钉的马面前有障碍物,即被“别马腿”,那么他将不能跳向有障碍物的左前和右前这两个方向。
请问最少需要多少步,大钉才能骑着马跳到终点。
有多组测试样例。
每组第一行有两个数 n 和 m,代表矩阵的行数和列数,2 <= n <= m < 100。
接下来输入 n 行的字符串,其中 's' 代表起点,'e' 代表终点,'.'代表空地,'#'代表障碍物。
对应每组输入,输出骑马跳到终点的最小步数,如果跳不到终点,输出 -1。
复制
3 3 s.. ... ..e 3 3 s#. ... #.e
4 -1
首先确认下能用bfs做后就比较容易写了,比较麻烦的是剪枝。
如何依次试探当前棋子可达的八个位置,还要不能被“别马腿”。
#include<iostream>
#include<string.h>
#include<math.h>
#include<queue>
#define M 105
using namespace std;
char map[M][M];
int vis[M][M];
int dir[8][2] = {{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
int n,m,sx,sy,ex,ey,min,ans;
struct node{
int x,y,step;
};
int check(int x,int y)
{
if(x<0||x>=n||y<0||y>=m)
return 1;
if(vis[x][y]||map[x][y]=='#')
return 1;
return 0;
}
int bfs()
{
queue<node> Q;
node now,next;
now.x = sx;
now.y = sy;
now.step = 0;
vis[now.x][now.y] = 1;
Q.push(now);
ans = 0;
while(!Q.empty())
{
now = Q.front();
Q.pop();
if(map[now.x][now.y]=='e' )
{
ans = 1;
return now.step;
}
for(int i = 0; i < 8;i++)
{
next = now;
//优化后的写法,可能做得多了后能一眼看出来吧..
// if(map[now.x+dir[i][0]/2][now.y+dir[i][1]/2]=='#')
// continue;
//想当然的,错误的写法
// if(abs(dir[i][0])==1&&map[now.x][now.y+dir[i][0]]=='#')
// continue;
// if(abs(dir[i][1])==1&&map[now.x+dir[i][1]][now.y]=='#')
// continue;
//有点啰嗦但正确的写法
if((i==0)&&(map[now.x][now.y+1]=='#'))
continue;
if((i==1)&&(map[now.x][now.y-1]=='#'))
continue;
if((i==2)&&(map[now.x][now.y+1]=='#'))
continue;
if((i==3)&&(map[now.x][now.y-1]=='#'))
continue;
if((i==4)&&(map[now.x+1][now.y]=='#'))
continue;
if((i==5)&&(map[now.x+1][now.y]=='#'))
continue;
if((i==6)&&(map[now.x-1][now.y]=='#'))
continue;
if((i==7)&&(map[now.x-1][now.y]=='#'))
continue;
next.x+=dir[i][0];
next.y+=dir[i][1];
if(check(next.x,next.y))
continue;
next.step = now.step+1;
Q.push(next);
vis[next.x][next.y] = 1;
}
}
if(!ans)
return -1;
}
int main()
{
freopen("chess.txt","r",stdin);
while(cin>>n>>m)
{
memset(vis,0,sizeof(vis));
memset(map,'\0',sizeof(map));
for(int i = 0; i < n;i++)
scanf("%s",&map[i]);
for(int i = 0; i < n;i++)
for(int j = 0;j < m;j++)
if(map[i][j]=='s')
{
sx = i;sy = j;
cout<<bfs()<<endl;
}
}
}