1107. 魔板

将棋盘编码成字符串,然后利用哈希表判重+记录距离。

char g[2][4];
unordered_map<string, int> dist;
unordered_map<string, string> path;
string st,ed;

void put(string s)
{
    for(int i = 0; i < 4; i++) g[0][i] = s[i];
    for(int i = 0; i < 4; i++) g[1][i] = s[7 - i];
}

string get()
{
    string res;
    for(int i = 0; i < 4; i++) res += g[0][i];
    for(int i = 0; i < 4; i++) res += g[1][3 - i];
    return res;
}

string moveA(string s)
{
    put(s);
    for(int i = 0; i < 4; i++) swap(g[0][i], g[1][i]);
    return get();
}

string moveB(string s)
{
    put(s);
    char last[2] = {g[0][3], g[1][3]};
    for(int i = 0; i < 2; i++)
        for(int j = 2; j >= 0; j--)  // 一定要倒序循环!
            g[i][j+1] = g[i][j];
    g[0][0] = last[0], g[1][0] = last[1];
    return get();
}

string moveC(string s)
{
    put(s);
    char temp = g[0][1];
    g[0][1] = g[1][1];
    g[1][1] = g[1][2];
    g[1][2] = g[0][2];
    g[0][2] = temp;
    return get();
}

int bfs()
{
    queue<string> q;
    q.push(st);
    dist[st]=0;

    while(q.size())
    {
        string t = q.front();
        q.pop();

        if(t == ed) return dist[t];

        string s[3];
        s[0] = moveA(t), s[1] = moveB(t), s[2] = moveC(t);
        for(int i = 0; i < 3; i++)
            if(dist.count(s[i]) == 0)
            {
                dist[s[i]] = dist[t] + 1;
                path[s[i]] = path[t] + char('A' + i);
                q.push(s[i]);
            }
    }
}

int main()
{
    st = "12345678";
    for(int i = 0; i < 8; i++)
    {
        char c;
        cin >> c;
        ed += c;
    }

    int t = bfs();
    cout << t << endl;
    if(path[ed].size()) cout << path[ed] << endl;
    //system("pause");
    return 0;
}
posted @ 2021-06-22 16:39  Dazzling!  阅读(44)  评论(0编辑  收藏  举报