1 条题解

  • 0
    @ 2025-5-26 20:57:44

    题意分析

    题目给出一个长方体,让它移动到规定的目标,但是途中可能会遇到障碍,长方体只能绕过障碍,求移动的最少次数,并且长方体的初始的顶面和最后的顶面必须一致。

    解题思路

    题目要求长方体的顶面和最后的顶面必须一致,因此我们必须记录长方体的顶面,但是一个顶面并不能确定一个长方体的面的位置,因此添加一个前面。用顶面和前面来记住长方体的状态。长方体每次移动可以有四个方向,因此,还需要一个移动函数,考虑顶面和前面的变化。题目求解的是最少步数,因此使用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
    上传者