【题目描述】
小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次。于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间。
小 B 玩的华容道与经典的华容道游戏略有不同,游戏规则是这样的:
1.在一个 n*m 棋盘上有 n*m 个格子,其中有且只有一个格子是空白的,其余 n*m-1个格子上每个格子上有一个棋子,每个棋子的大小都是 1*1 的;
2.有些棋子是固定的,有些棋子则是可以移动的;
3.任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白格子上。 游戏的目的是把某个指定位置可以活动的棋子移动到目标位置。
给定一个棋盘,游戏可以玩 q 次,当然,每次棋盘上固定的格子是不会变的,但是棋盘上空白的格子的初始位置、指定的可移动的棋子的初始位置和目标位置却可能不同。第 i 次玩的时候,空白的格子在第 EXi 行第 EYi 列,指定的可移动棋子的初始位置为第 SXi 行第 SYi列,目标位置为第 TXi 行第 TYi 列。
假设小 B 每秒钟能进行一次移动棋子的操作,而其他操作的时间都可以忽略不计。请你告诉小 B 每一次游戏所需要的最少时间,或者告诉他不可能完成游戏。
【输入】
第一行有 3 个整数,每两个整数之间用一个空格隔开,依次表示 n、m 和 q;
接下来的 n 行描述一个 n*m 的棋盘,每行有 m 个整数,每两个整数之间用一个空格隔开,每个整数描述棋盘上一个格子的状态,0 表示该格子上的棋子是固定的,1 表示该格子上的棋子可以移动或者该格子是空白的。
接下来的 q 行,每行包含 6 个整数依次是 EXi、EYi、SXi、SYi、TXi、TYi,每两个整数之间用一个空格隔开,表示每次游戏空白格子的位置,指定棋子的初始位置和目标位置。
【输出】
输出有 q 行,每行包含 1 个整数,表示每次游戏所需要的最少时间,如果某次游戏无法完成目标则输出−1。
【输入样例】
3 4 2
0 1 1 1
0 1 1 0
0 1 0 0
3 2 1 2 2 2
1 2 2 2 3 2
【输出样例】
2
-1
【提示】
【输入输出样例说明】
棋盘上划叉的格子是固定的,红色格子是目标位置,圆圈表示棋子,其中绿色圆圈表示目标棋子。
1. 第一次游戏,空白格子的初始位置是(3,2)(图中空白所示),游戏的目标是将初始位置在(1,2)上的棋子(图中绿色圆圈所代表的棋子)移动到目标位置(2, 2)(图中红色的格子)上。
移动过程如下:
2. 第二次游戏,空白格子的初始位置是(1, 2)(图中空白所示),游戏的目标是将初始位置在(2,2)上的棋子(图中绿色圆圈所示)移动到目标位置(3, 2)上。
要将指定块移入目标位置,必须先将空白块移入目标位置,空白块要移动到目标位置,必然是从位置(2,2)上与当前图中目标位置上的棋子交换位置,之后能与空白块交换位置的只有当前图中目标位置上的那个棋子,因此目标棋子永远无法走到它的目标位置,游戏无法完成。
【数据范围】
对于 30%的数据,1 ≤ n, m ≤ 10,q = 1;
对于 60%的数据,1 ≤ n, m ≤ 30,q ≤ 10;
对于 100%的数据,1 ≤ n, m ≤ 30,q ≤ 500。
直接上代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define re register
#define LL long long
#define rep(i, x, y) for (register int i = x; i <= y; ++i)
#define repd(i, x, y) for (register int i = x; i >= y; --i)
#define maxx(a, b) a = max(a, b)
#define minn(a, b) a = min(a, b)
#define inf 1e9
#define linf 1e17
inline int read() {
re int w = 0, f = 1; char c = getchar();
while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar();
while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ 48), c = getchar();
return w * f;
}
const int maxn = 30 + 5;
struct State {
int x, y, d;
};
queue<State> q;
struct Edge {
int u, v, w, pre;
};
inline int convert(int x, int y, int d) {
return x * 120 + y * 4 + d;
}
struct Node {
int u, d;
bool operator < (const Node &rhs) const {
return d > rhs.d;
}
};
priority_queue <Node> Q;
struct Graph {
Edge edges[maxn * maxn * maxn];
int G[maxn * maxn * maxn], n, m;
int d[maxn * maxn * maxn], vis[maxn * maxn * maxn];
void init(int n) {
this->n = n;
m = 0;
memset(G, 0, sizeof(G));
}
void AddEdge(int u, int v, int w) {
edges[++m] = (Edge){u, v, w, G[u]};
G[u] = m;
}
void dijkstra() {
memset(vis, 0, sizeof(vis));
while (!Q.empty()) {
re Node head = Q.top(); Q.pop();
int u = head.u;
if (vis[u]) continue;
vis[u] = 1;
for (re int i = G[u]; i; i = edges[i].pre) {
Edge &e = edges[i];
if (!vis[e.v] && d[u] + e.w < d[e.v]) {
d[e.v] = d[u] + e.w;
Q.push((Node){e.v, d[e.v]});
}
}
}
}
} G;
int fx[4] = {0, 1, 0, -1};
int fy[4] = {1, 0, -1, 0};
int n, m, t;
int a[maxn][maxn], vis[maxn][maxn], dis[maxn][maxn];
void bfs(int X, int Y) {
memset(dis, 0x3f, sizeof(dis));
dis[X][Y] = 0;
q.push((State){X, Y, 0});
while (!q.empty()) {
State head = q.front(); q.pop();
dis[head.x][head.y] = head.d;
rep(i, 0, 3) {
re int x = head.x + fx[i], y = head.y + fy[i];
if (a[x][y] && !vis[x][y]) {
vis[x][y] = 1;
dis[x][y] = head.d + 1;
q.push((State){x, y, dis[x][y]});
}
}
}
}
int main() {
n = read(), m = read(), t = read();
rep(i, 1, n)
rep(j, 1, m)
a[i][j] = read();
G.init(n * n * 4);
rep(X, 1, n)
rep(Y, 1, m)
if (a[X][Y]) {
rep(i, 0, 3) {
re int x = X + fx[i], y = Y + fy[i];
if (a[x][y]) {
memset(vis, 0, sizeof(vis));
vis[x][y] = vis[X][Y] = 1;
bfs(x, y);
rep(j, 0, 3) {
re int x2 = X + fx[j], y2 = Y + fy[j];
if (i == j || !a[x2][y2]) continue;
G.AddEdge(convert(X, Y, i), convert(X, Y, j), dis[x2][y2]);
}
}
}
if (a[X][Y + 1]) G.AddEdge(convert(X, Y, 0), convert(X, Y + 1, 2), 1);
if (a[X + 1][Y]) G.AddEdge(convert(X, Y, 1), convert(X + 1, Y, 3), 1);
if (a[X][Y - 1]) G.AddEdge(convert(X, Y, 2), convert(X, Y - 1, 0), 1);
if (a[X - 1][Y]) G.AddEdge(convert(X, Y, 3), convert(X - 1, Y, 1), 1);
}
re int Ex, Ey, Sx, Sy, Tx, Ty;
while (t--) {
Ex = read(), Ey = read(), Sx = read(), Sy = read(), Tx = read(), Ty = read();
if (Sx == Tx && Sy == Ty) {
printf("0\n");
continue;
}
memset(vis, 0, sizeof(vis));
vis[Ex][Ey] = vis[Sx][Sy] = 1;
bfs(Ex, Ey);
memset(G.d, 0x3f, sizeof(G.d));
rep(i, 0, 3) {
Q.push((Node){convert(Sx, Sy, i), dis[Sx + fx[i]][Sy + fy[i]]});
G.d[convert(Sx, Sy, i)] = dis[Sx + fx[i]][Sy + fy[i]];
}
G.dijkstra();
re int ans = inf;
rep(i, 0, 3)
if (a[Tx + fx[i]][Ty + fy[i]]) minn(ans, G.d[convert(Tx, Ty, i)]);
if (ans == inf) printf("-1\n");
else printf("%d\n", ans);
}
return 0;
}
帅哥美女们点个在再走吧球球了~