1 条题解
-
0
题意分析
题目给出一个长方体,让它移动到规定的目标,但是途中可能会遇到障碍,长方体只能绕过障碍,求移动的最少次数,并且长方体的初始的顶面和最后的顶面必须一致。
解题思路
题目要求长方体的顶面和最后的顶面必须一致,因此我们必须记录长方体的顶面,但是一个顶面并不能确定一个长方体的面的位置,因此添加一个前面。用顶面和前面来记住长方体的状态。长方体每次移动可以有四个方向,因此,还需要一个移动函数,考虑顶面和前面的变化。题目求解的是最少步数,因此使用bfs求解。
标程
#include <iostream> #include <queue> #include <tuple> #include <set> #include <map> #include <string> using namespace std; const int opposite[] = {0, 6, 5, 4, 3, 2, 1}; const int adj[7][4] = { {0,0,0,0}, // dummy {2,3,5,4}, // T=1: front=2, right=3, back=5, left=4 {1,4,6,3}, // T=2: front=1, right=4, back=6, left=3 {1,5,6,2}, // T=3: front=1, right=5, back=6, left=2 {1,2,6,5}, // T=4: front=1, right=2, back=6, left=5 {1,4,6,3}, // T=5: front=1, right=4, back=6, left=3 {2,4,5,3} // T=6: front=2, right=4, back=5, left=3 }; pair<int, int> roll(int T, int F, const string& dir) { if (dir == "east") return {adj[T][3], F}; // 左面变顶面 if (dir == "west") return {adj[T][1], F}; // 右面变顶面 if (dir == "north") return {adj[T][2], T}; // 后面变顶面,原顶面变前面 if (dir == "south") return {F, opposite[T]}; // 前面变顶面,原顶面对面变前面 return {T, F}; } int main() { int X, Y, A, B, C, D; cin >> X >> Y >> A >> B >> C >> D; set<pair<int, int>> ver, hor; string line; while (cin >> line) { if (line == "v") { int M, N; while (cin >> M >> N) { ver.insert({N, M}); if (cin.get() == '\n') break; } } else if (line == "h") { int M, N; while (cin >> M >> N) { hor.insert({N, M}); if (cin.get() == '\n') break; } } } using State = tuple<int, int, int, int>; queue<State> q; map<State, int> vis; const int T0 = 1, F0 = 2; q.emplace(A, B, T0, F0); vis[{A, B, T0, F0}] = 0; vector<tuple<string, int, int>> dirs = { {"east", 1,0}, {"west", -1,0}, {"north", 0,1}, {"south", 0,-1} }; int ans = -1; while (!q.empty()) { auto [x, y, T, F] = q.front(); int steps = vis[{x, y, T, F}]; q.pop(); if (x == C && y == D && T == T0) { ans = steps; break; } for (auto& [d, dx, dy] : dirs) { int nx = x + dx, ny = y + dy; if (nx < 1 || nx > X || ny < 1 || ny > Y) continue; bool blocked = false; if (d == "east" && ver.count({y, x})) blocked = true; else if (d == "west" && ver.count({y, nx})) blocked = true; else if (d == "north" && hor.count({x, y})) blocked = true; else if (d == "south" && hor.count({x, ny})) blocked = true; if (blocked) continue; auto [nT, nF] = roll(T, F, d); State new_state = {nx, ny, nT, nF}; if (!vis.count(new_state)) { vis[new_state] = steps + 1; q.push(new_state); } } } cout << (ans != -1 ? to_string(ans) : "no") << endl; }
- 1
信息
- ID
- 1619
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者