下象棋
发布时间: 2018年1月25日 20:25 最后更新: 2018年1月25日 20:26 时间限制: 1000ms 内存限制: 128M
江湖是什么,对于在象棋界厮杀的QQ来说,江湖就是一个矩阵,他的目标,就是在江湖之中骑着马,从他的位置出发,走到终点。
当然,QQ的马也遵从中国象棋中的“马走日”的规则,而且在矩阵中,也会有一些障碍物,马不能跳到障碍物上;如果大钉的马面前有障碍物,即被“别马腿”,那么他将不能跳向有障碍物的左前和右前这两个方向。
请问最少需要多少步,大钉才能骑着马跳到终点。
有多组测试样例。
每组第一行有两个数 n 和 m,代表矩阵的行数和列数,2 <= n <= m < 100。
接下来输入 n 行的字符串,其中 ‘s‘ 代表起点,‘e‘ 代表终点,‘.‘代表空地,‘#‘代表障碍物。
对应每组输入,输出骑马跳到终点的最小步数,如果跳不到终点,输出 -1。
3 3
s..
...
..e
3 3
s#.
...
#.e
4
-1
#include <stdio.h> #include <string.h> #include <iostream> #include <queue> #include <algorithm> using namespace std; struct dian { int i; int j; int step; }; char map[110][110]; int vis[110][110]; int dir[8][2] = { { -2,1 },{ -1,2 },{ 1,2 },{ 2,1 },{ 2,-1 },{ 1,-2 },{ -1,-2 },{ -2,-1 } }; int main() { int n, m; queue<dian>q; while (scanf("%d%d", &n, &m) != EOF) { dian now, next; bool tp = false; int i, j; for (i = 0; i < n; i++)scanf("%s", map[i]); memset(vis, 0, sizeof(vis)); while (!q.empty())q.pop(); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { if (map[i][j] == ‘s‘) { now.i = i; now.j = j; now.step = 0; tp = true; break; } } if (tp==true)break; } int flag = 0; q.push(now); while (!q.empty()) { now = q.front(); q.pop(); if (map[now.i][now.j] == ‘e‘) { flag = 1; break; } /*if (vis[now.i][now.j])continue;*/ vis[now.i][now.j] = 1; for (i = 0; i < 8; i++) { next.i = now.i + dir[i][0]; next.j = now.j + dir[i][1]; if (next.i<0 || next.i >= n || next.j<0 || next.j >= m) continue; if (vis[next.i][next.j]) continue; if (abs(dir[i][0]) == 2 && map[now.i + dir[i][0] / 2][now.j] == ‘#‘) continue; if (abs(dir[i][1]) == 2 && map[now.i][now.j + dir[i][1] / 2] == ‘#‘) continue; if (map[next.i][next.j] == ‘.‘ || map[next.i][next.j] == ‘e‘) { next.step = now.step + 1; q.push(next); } } } flag ? printf("%d\n", now.step) : printf("-1\n"); } return 0; }
2018-03-31