原题网址:http://nanti.jisuanke.com/t/11064
江湖是什么,对于在象棋界厮杀的大钉来说,江湖就是一个矩阵,他的目标,就是在江湖之中骑着马,从他的位置出发,走到终点。
当然,大钉的马也遵从中国象棋中的“马走日”的规则,而且在矩阵中,也会有一些障碍物,马不能跳到障碍物上;如果大钉的马面前有障碍物,即被“别马腿”,那么他将不能跳向有障碍物的左前和右前这两个方向。
请问最少需要多少步,大钉才能骑着马跳到终点。
输入格式:
有多组测试样例。
每组第一行输入两个数 nn 和 mm,代表矩阵的行数和列数,2 \leq n \leq m < 1002≤n≤m<100。
接下来输入 nn 行字符串,其中 's' 代表起点,'e' 代表终点,'.' 代表空地,'#' 代表障碍物。
输出格式:
对应每组输入,输出骑马跳到终点的最小步数,如果跳不到终点,输出 -1−1。
输入:
3 3 s.. ... ..e 3 3 s#. ... #.e
输出:
4 -1
题解:
不难想到bfs 暴力搜索的解法,象棋中“马战八方”,如果不考虑蹩腿和越界,至少要枚举八个位置,而这道题蹩马腿就是剪枝的条件了,特别注意常量数组的对应关系
/* http://blog.csdn.net/liuke19950717 */ #include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; const int maxn=105; char map[maxn][maxn]; int n,m; int dh[8][2]={{-1,-2},{-1,2},{1,2},{1,-2},{2,1},{2,-1},{-2,1},{-2,-1}}; int dht[8][2]={{0,-1},{0,1},{0,1},{0,-1},{1,0},{1,0},{-1,0},{-1,0}}; struct node { int x,y,time; }; int bfs(int bx,int by,int ex,int ey) { int vis[maxn][maxn]={0}; queue<node> q; node st={bx,by,0}; vis[bx][by]=1; q.push(st); while(!q.empty()) { st=q.front();q.pop(); if(st.x==ex&&st.y==ey) { return st.time; } for(int i=0;i<8;++i) { int tx=st.x+dh[i][0],ty=st.y+dh[i][1]; if(tx<0||tx>=n||ty<0||ty>=m||map[tx][ty]=='#') { continue; } int sx=st.x+dht[i][0],sy=st.y+dht[i][1]; if(map[sx][sy]=='#') { continue; } if(!vis[tx][ty]) { vis[tx][ty]=1; node tp={tx,ty,st.time+1}; q.push(tp); } } } return -1; } int main() { while(~scanf("%d%d",&n,&m)) { for(int i=0;i<n;++i) { scanf("%s",map[i]); } int bx,by,ex,ey; for(int i=0;i<n;++i) { for(int j=0;j<m;++j) { if(map[i][j]=='s') { bx=i;by=j; } else if(map[i][j]=='e') { ex=i;ey=j; } } } printf("%d\n",bfs(bx,by,ex,ey)); } return 0; }