魔板 —— BFS最小步数

题面

题目
魔板 —— BFS最小步数

魔板 —— BFS最小步数
魔板 —— BFS最小步数

思路

我们将整个魔板看成一个点(或者说一个状态);

然后对它进行A、B、C三种操作得到下一个状态;

这样我们就可以用BFS来解决;


将整个板子看成一个状态,我们可以先将整个板子拉成一条线;

用一个字符串来存储;

然后用哈希表来存即可;

Code

#include <iostream>
#include <cstdio>
#include <string>
#include <queue>
#include <utility>
#include <vector>
#include <unordered_map>
#include <algorithm>

using namespace std;

typedef long long ll;

const int N = 1e5 + 10;

string __start = "12345678",_end;

unordered_map<string,int> dist;

unordered_map<string,pair<char,string> > pre;

char now[2][5];

queue<string> que;

string get_now(){
    string ret;
    for(int i=0;i<4;++i) ret += now[0][i];
    for(int i=3;i>=0;--i) ret += now[1][i];
    return ret;
}
void set_now(string state){
    for(int i=0;i<4;++i) now[0][i] = state[i];
    for(int i=3,j=4;i>=0;--i,++j) now[1][i] = state[j];
}
//将state进行A变换,下同
string changeA(string state){
    set_now(state);
    for(int j=0;j<4;++j) swap(now[0][j],now[1][j]);
    return get_now();
}
string changeB(string state){
    set_now(state);
    char rtop = now[0][3],rdown = now[1][3];
    for(int j=2;j>=0;--j){
        now[0][j+1] = now[0][j];
        now[1][j+1] = now[1][j];
    }
    now[0][0] = rtop,now[1][0] = rdown;
    return get_now();
}
string changeC(string state){
    set_now(state);
    char ltop = now[0][1];
    now[0][1] = now[1][1];
    now[1][1] = now[1][2];
    now[1][2] = now[0][2];
    now[0][2] = ltop;
    return get_now();
}

void bfs(){
    dist[__start] = 0;
    if(_end == __start){
        dist[_end] = 0;
        return;
    }
    que.push(__start);
    while(!que.empty()){
        auto u = que.front();
        que.pop();
        vector<string> ve;
        ve.push_back(changeA(u));
        ve.push_back(changeB(u));
        ve.push_back(changeC(u));
        int cnt = 0;//A,B,C
        for(auto v : ve){
            if(dist.count(v) == 0){
                dist[v] = dist[u] + 1;
                pre[v] = {'A'+cnt,u};
                que.push(v);
                if(v == _end) return;
            }
            ++cnt;
        }
    }
}
void solve(){
    for(int i=1,x;i<=8;++i){
        cin >> x;
        _end += char(x+'0');
    }
    bfs();
    cout << dist[_end] << '\n';
    string init = _end;
    string ans;
    while(_end != __start){
        ans += pre[_end].first;
        _end = pre[_end].second;
    }
    reverse(ans.begin(),ans.end());
    if(dist[init] > 0) cout << ans << '\n';
}

int main(){
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    solve();
    return 0;
}
上一篇:6.6 搜索讲解


下一篇:Knight Moves(BFS模板)