ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

day1.魔板

2022-05-11 20:34:00  阅读:144  来源: 互联网

标签:魔板 return string int day1 start end dist



最小步数模型


跟传统网格bfs不同,每个状态是一个网格,状态为棋盘到棋盘间,构成有向图,求有向图的最短路径


魔板

每个点可以由操作A、B、C向三个方向扩展,以整个魔板为状态,容易想到通过bfs,从satrt开始扩展到end,每个状态可以有3个扩展方向。

如何保证序列字典序最小:由于每个状态的操作序列不同,若存在end,只需要按照A、B、C顺序扩展,就一定有字典序最小的序列。(下图三叉树解释)

如图所示,每个状态三条分支,当分支有交叉时,此状态一定由更小的操作数先转移过,因此可以保证字典序最小。


CODE
求路径

while(end != start)
    {
        res += pre[end].first;
        end = pre[end].second;
    }


完整代码

#include<iostream>
#include<unordered_map>
#include<algorithm>
#include<queue>
using namespace std;

int g[2][4];
unordered_map<string,int> dist;
unordered_map<string,pair<char,string>> pre;

void set(string s)
{
    for(int i = 0;i < 4;i++) g[0][i] = s[i];
    for(int j = 4,i = 3;j < 8;i--,j++) g[1][i] = s[j];
}

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

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

string workB(string s)
{
    set(s);
    char a = g[0][3],b = g[1][3];
    for(int i = 3;i >= 1;i--) 
    {
        g[0][i] = g[0][i-1];
        g[1][i] = g[1][i-1];
    }
    g[0][0] = a,g[1][0] = b;
    return get();
}

string workC(string s)
{
    set(s);
    char v = g[0][1];
    g[0][1] = g[1][1];
    g[1][1] = g[1][2];
    g[1][2] = g[0][2];
    g[0][2] = v;
    
    return get();
}

int bfs(string start,string end)
{
    if(start == end) return 0;
    
    dist[start] = 0;
    
    queue<string> q;
    q.push(start);
    
    while(q.size())
    {
        auto t = q.front();
        q.pop();
        
        string m[3];
        m[0] = workA(t);
        m[1] = workB(t);
        m[2] = workC(t);
        
        for(int i = 0;i < 3;i++)
        {
            if(dist[m[i]] == 0)
            {
                dist[m[i]] = dist[t] + 1;
                pre[m[i]] = {'A' + i,t};
                q.push(m[i]);
                if(m[i] == end) return dist[end];
            }
        }
    }
    return -1;
}
int main()
{
    string start = "12345678",end;
    for(int i = 0;i < 8;i++)
    {
        int x;cin>>x;
        end += x + '0';
    }
    
    int step = bfs(start,end);
    
    cout<<step<<endl;
    
    if(step)
    {
        string res;
        while(end != start)
        {
            res += pre[end].first;
            end = pre[end].second;
        }
        reverse(res.begin(),res.end());
        cout<<res<<endl;
    }
    return 0;
}

标签:魔板,return,string,int,day1,start,end,dist
来源: https://www.cnblogs.com/wei-ak1/p/16259644.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有