八数码+魔板——BFS(最小步数模型)

2023-10-07 00:05

本文主要是介绍八数码+魔板——BFS(最小步数模型),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、八数码

在一个 3×3 的网格中,1∼8 这 8 个数字和一个 x 恰好不重不漏地分布在这 3×3 的网格中。

例如:

1 2 3
x 4 6
7 5 8

在游戏过程中,可以把 x 与其上、下、左、右四个方向之一的数字交换(如果存在)。

我们的目的是通过交换,使得网格变为如下排列(称为正确排列):

1 2 3
4 5 6
7 8 x

例如,示例中图形就可以通过让 x 先后与右、下、右三个方向的数字交换成功得到正确排列。

交换过程如下:

1 2 3   1 2 3   1 2 3   1 2 3
x 4 6   4 x 6   4 5 6   4 5 6
7 5 8   7 5 8   7 x 8   7 8 x

现在,给你一个初始网格,请你求出得到正确排列至少需要进行多少次交换。

输入格式
输入占一行,将 3×3 的初始网格描绘出来。

例如,如果初始网格如下所示:

1 2 3 
x 4 6 
7 5 8 

则输入为:1 2 3 x 4 6 7 5 8

输出格式
输出占一行,包含一个整数,表示最少交换次数。
如果不存在解决方案,则输出 −1。

输入样例:
2 3 4 1 5 x 7 6 8

输出样例
19

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
typedef pair<int,int> PII;
const int N=2e6+10;
char g[3][3];
unordered_map <string,int> k;
queue <string> q;
string s,p;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void Set(string s)
{int l=0;for (int i=0;i<3;i++)for (int j=0;j<3;j++)g[i][j]=s[l++];
}
string Get()
{string s;for (int i=0;i<3;i++)for (int j=0;j<3;j++)s +=g[i][j];return s;
}
void bfs()
{k[s]=0;q.push(s);while (q.size()&&k.count(p)==0){string t=q.front();q.pop();Set(t);int x,y;for (int i=0;i<3;i++)for (int j=0;j<3;j++){if (g[i][j]=='x'){x=i;y=j;break;}}for (int i=0;i<4;i++){Set(t);int a=x+dx[i],b=y+dy[i];if (a>=0&&a<3&&b>=0&&b<3){swap(g[a][b],g[x][y]);string s1=Get();if (k.count(s1)==0){k[s1]=k[t]+1;q.push(s1);}}}}
}
signed main()
{ios;for (int i=0;i<9;i++){char c;cin>>c;s +=c;}for (int i=1;i<9;i++) p +=char(i+'0');p +='x';bfs();if (k.count(p)==0) cout<<"-1";else cout<<k[p];return 0;
}

二、魔板

Rubik 先生在发明了风靡全球的魔方之后,又发明了它的二维版本——魔板。
这是一张有 8 个大小相同的格子的魔板:

1 2 3 4
8 7 6 5

我们知道魔板的每一个方格都有一种颜色。这 8 种颜色用前 8 个正整数来表示。
可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。

对于上图的魔板状态,我们用序列 (1,2,3,4,5,6,7,8) 来表示,这是基本状态。

这里提供三种基本操作,分别用大写字母 A,B,C 来表示(可以通过这些操作改变魔板的状态):

A:交换上下两行;
B:将最右边的一列插入到最左边;
C:魔板中央对的4个数作顺时针旋转。

下面是对基本状态进行操作的示范:

A:

8 7 6 5
1 2 3 4

B:

4 1 2 3
5 8 7 6

C:

1 7 2 4
8 6 3 5

对于每种可能的状态,这三种基本操作都可以使用。

你要编程计算用最少的基本操作完成基本状态到特殊状态的转换,输出基本操作序列。

注意:数据保证一定有解。

输入格式
输入仅一行,包括 8 个整数,用空格分开,表示目标状态。

输出格式
输出文件的第一行包括一个整数,表示最短操作序列的长度。
如果操作序列的长度大于0,则在第二行输出字典序最小的操作序列。

数据范围
输入数据中的所有数字均为 1 到 8 之间的整数。

输入样例:

2 6 8 4 5 7 3 1

输出样例:

7
BCABCCB

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
typedef pair<int,int> PII;
const int N=2e6+10;
char g[2][4];
string s,p;
unordered_map <string,int> k;
unordered_map <string,pair<char,string>> m;
queue <string> q;
void Set(string s)
{int l=0;for (int i=0;i<4;i++) g[0][i]=s[l++];for (int i=3;i>=0;i--) g[1][i]=s[l++];
}
string Get()
{string s;for (int i=0;i<4;i++) s+=g[0][i];for (int i=3;i>=0;i--) s+=g[1][i];return s;
}
string move1(string s)
{Set(s);for (int i=0;i<4;i++) swap(g[0][i],g[1][i]);return Get();
}
string move2(string s)
{Set(s);char a=g[0][3],b=g[1][3];for (int i=3;i>0;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 move3(string s)
{Set(s);char a=g[0][1];g[0][1]=g[1][1];g[1][1]=g[1][2];g[1][2]=g[0][2];g[0][2]=a;return Get();
}
void bfs()
{k[s]=0;q.push(s);while (q.size()&&k.count(p)==0){string t=q.front();q.pop();string s1[3];s1[0]=move1(t);s1[1]=move2(t);s1[2]=move3(t);for (int i=0;i<3;i++){if (k.count(s1[i])==0){q.push(s1[i]);k[s1[i]]=k[t]+1;m[s1[i]]={char(i+'A'),t};}}}
}
signed main()
{ios;for (int i=0;i<8;i++){char c;cin>>c;p +=c;}for (int i=1;i<9;i++) s+=char(i+'0');bfs();cout<<k[p]<<endl;string ans;while (s!=p){ans=m[p].first+ans;p=m[p].second;}if (ans.size()) cout<<ans;return 0;
}

这篇关于八数码+魔板——BFS(最小步数模型)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/154779

相关文章

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

如何在本地部署 DeepSeek Janus Pro 文生图大模型

《如何在本地部署DeepSeekJanusPro文生图大模型》DeepSeekJanusPro模型在本地成功部署,支持图片理解和文生图功能,通过Gradio界面进行交互,展示了其强大的多模态处... 目录什么是 Janus Pro1. 安装 conda2. 创建 python 虚拟环境3. 克隆 janus

本地私有化部署DeepSeek模型的详细教程

《本地私有化部署DeepSeek模型的详细教程》DeepSeek模型是一种强大的语言模型,本地私有化部署可以让用户在自己的环境中安全、高效地使用该模型,避免数据传输到外部带来的安全风险,同时也能根据自... 目录一、引言二、环境准备(一)硬件要求(二)软件要求(三)创建虚拟环境三、安装依赖库四、获取 Dee

DeepSeek模型本地部署的详细教程

《DeepSeek模型本地部署的详细教程》DeepSeek作为一款开源且性能强大的大语言模型,提供了灵活的本地部署方案,让用户能够在本地环境中高效运行模型,同时保护数据隐私,在本地成功部署DeepSe... 目录一、环境准备(一)硬件需求(二)软件依赖二、安装Ollama三、下载并部署DeepSeek模型选

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

hdu1254(嵌套bfs,两次bfs)

/*第一次做这种题感觉很有压力,思路还是有点混乱,总是wa,改了好多次才ac的思路:把箱子的移动当做第一层bfs,队列节点要用到当前箱子坐标(x,y),走的次数step,当前人的weizhi(man_x,man_y),要判断人能否将箱子推到某点时要嵌套第二层bfs(人的移动);代码如下: