题目链接:http://lx.lanqiao.cn/problem.page?gpid=T42

题意:中文题诶~

思路:bfs

将没种九宫格的状态看作一个状态节点,那么只需求起始节点到目标节点的最短路径即可,可以用bfs解决。

代码:

 #include <iostream>
#include <string>
#include <string.h>
#include <queue>
#include <map>
#define MAXN 9
using namespace std; struct node{
int matrix[MAXN];//**存储当前九宫格状态
int v;
bool operator <(const node &r) const{//**后面用map标记,map是有序对,需要重载比较运算符
for(int i=; i<MAXN; i++){
if(matrix[i]!=r.matrix[i]){
return matrix[i]<r.matrix[i];
}
}
return r.matrix[]<matrix[];
}
}; const int dir[][]={, , , -, , , -, };//记录方向
map<node, bool> mp;//标记节点 bool is_ok(node q, node e){//判断是否达到目标状态
for(int i=; i<; i++){
if(q.matrix[i]!=e.matrix[i]){
return false;
}
}
return true;
} void scan(string str, node &r){//将输入字符串转化为状态数组
for(int i=; i<; i++){
int x=str[i]-'';
if(x>=&&x<=){
r.matrix[i]=x;
}else{
r.matrix[i]=;
r.v=i;
}
}
} int bfs(node s, node e){//bfs开始状态与目标状态的最短距离
int ans=;
queue<node> q;
q.push(s);
mp[s]=true;
if(is_ok(s, e)){//达到目标状态
return ans;
}
int gg[MAXN];
while(!q.empty()){//搜索目标状态
int q_size=q.size();
while(q_size--){
node now=q.front(), cc;
q.pop();
int x=now.v/, y=now.v%;
for(int i=; i<; i++){
int fx=x+dir[i][];
int fy=y+dir[i][];
if(fx>=&&fx<&&fy>=&&fy<){
int v=fx*+fy;
memcpy(gg, now.matrix, sizeof(now.matrix));
swap(gg[v], gg[now.v]);
memcpy(cc.matrix, gg, sizeof(gg));
cc.v=v;
if(mp[cc]) continue;
if(is_ok(cc, e)){//判断是否达到目标状态
return ans+;
}
mp[cc]=true;//标记
q.push(cc);//入队
}
}
}
ans++;
}
return -;
} int main(void){
string str1, str2;
int x;
node s, e;
cin >> str1 >> str2;
scan(str1, s);
scan(str2, e);
int ans=bfs(s, e);
cout << ans << endl;
return ;
}

如果步数比较多的话,可以用数组模拟队列

代码:

 #include <iostream>
#include <string.h>
using namespace std; typedef int State[]; //定义状态类
const int MAXN=1e6+;
const int hashsize=1e6+;
State st[MAXN], goal; //状态数组
int dist[MAXN]; //距离数组
int head[hashsize], next[hashsize]; const int dx[]={-, , , };
const int dy[]={, , -, }; int hash(State& s){//hash一下,标记节点
int v=;
for(int i=; i<; i++){
v=v*+s[i];
}
return v%hashsize;
} int try_to_insert(int s){
int h=hash(st[s]);
int u=head[h];
while(u){
if(memcmp(st[s], st[u], sizeof(st[s]))==){
return ;
}
u=next[u];
}
next[s]=head[h];
head[h]=s;
return ;
} void init() {
memset(head, , sizeof(head));
} int bfs(void){ //返回目标状态在st数组的下标
init(); //初始化
int front=, rear=; //从1开始
while(front<rear){
State& s=st[front];
if(memcmp(goal, s, sizeof(s))==){ //找到目标状态
return front;
}
int z;
for(z=; z<; z++){
if(!s[z]){ // 找到0的位置
break;
}
}
int x=z/, y=z%;
for(int i=; i<; i++){
int fx=x+dx[i], fy=y+dy[i];
int fz=fx*+fy;
if(fx>=&&fx<&&fy>=&&fy<){ //如果移动合法
State& t=st[rear];
memcpy(&t, &s, sizeof(s));//扩展新节点
t[fz]=s[z];
t[z]=s[fz];
dist[rear]=dist[front]+; //更新新节点的距离
if(try_to_insert(rear)){ //如果成功插入查找表,更新队尾指针
rear++;
}
}
}
front++; //扩展完毕后再修改队首指针
}
return ;
} int main(void){
string str1, str2;
cin >> str1 >> str2;
for(int i=; i<; i++){
if(str1[i]=='.'){
st[][i]=;
}else{
st[][i]=str1[i]-'';
}
}
for(int i=; i<; i++){
if(str2[i]=='.'){
goal[i]=;
}else{
goal[i]=str2[i]-'';
}
}
int ans=bfs();
if(ans>){
cout << dist[ans] << endl;
}else{
cout << - << endl;
}
return ;
}

蓝桥杯T42(八数码问题)的更多相关文章

  1. 第八届蓝桥杯JavaB组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.购物单 题目描述 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推 ...

  2. Java实现第八届蓝桥杯购物单

    购物单 题目描述 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打 ...

  3. Java实现 蓝桥杯 算法提高 八数码(BFS)

    试题 算法提高 八数码 问题描述 RXY八数码 输入格式 输入两个33表格 第一个为目标表格 第二个为检索表格 输出格式 输出步数 样例输入 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 ...

  4. 第四届蓝桥杯 c/c++真题

    第四届蓝桥杯 c/c++真题 <1>高斯日记 问题 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们 ...

  5. 【蓝桥杯单片机02】LED的基本控制

    [蓝桥杯单片机02]LED的基本控制 广东职业技术学院  欧浩源 在CT107D单片机综合训练平台实现LED的基本控制和其他单片机开发平台不一样,不单单是控制几个LED实现跑马灯这么简单.因为在这个平 ...

  6. 2018年第九届蓝桥杯题目(C/C++B组)汇总

    第一题 标题:第几天 2000年的1月1日,是那一年的第1天. 那么,2000年的5月4日,是那一年的第几天? 注意:需要提交的是一个整数,不要填写任何多余内容. 解题思路: 1.  判断2月有几天, ...

  7. 2017第八届蓝桥杯C/C++语言A组

    一:题目: 标题:迷宫 X星球的一处迷宫游乐场建在某个小山坡上.它是由10x10相互连通的小房间组成的. 房间的地板上写着一个很大的字母.我们假设玩家是面朝上坡的方向站立,则:L表示走到左边的房间,R ...

  8. 2016第七届蓝桥杯C/C++语言A组

    一:问题: 某君新认识一网友.当问及年龄时,他的网友说:“我的年龄是个2位数,我比儿子大27岁,如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄” 请你计算:网友的年龄一共有多少种可能情况? 提 ...

  9. 蓝桥杯第十届真题B组(2019年)

    2019年第十届蓝桥杯大赛软件类省赛C/C++大学B组# 试题 A:组队# 本题总分:5分[问题描述]作为篮球队教练,你需要从以下名单中选出 1号位至 5号位各一名球员,组成球队的首发阵容.每位球员担 ...

随机推荐

  1. MySQL 创建自定义函数(1)

    1. 创建测试自定义函数(1) CREATE DEFINER=`dbdh`@`localhost` FUNCTION `test`.`sp_function_dbdh_three`() RETURNS ...

  2. EasyPusher实现Android手机屏幕桌面直播,实时推送操作画面,用于手游直播等应用

    本文转自EasyDarwin开源团队成员John的博客:http://blog.csdn.net/jyt0551/article/details/52651194 由于Android 5.0提供了捕获 ...

  3. 页面滚动tab监听

    页面 需求,顶部固定,左侧固定,右侧内容滚动 所以给右侧内容高度,内容里面滚动(使用固定定位的话,右侧内容总会给head部分遮挡,比较坑) 1.左侧是侧边栏,点击li,右侧内容显示当前 右侧内容滚动, ...

  4. mongodb分页

    1 什么是mongodb的分页 就是一次返回表中的连续若干行. 2 什么是sql分页 同样是返回表中的连续若干行. 3 如何实现sql分页 利用order by xxx limit xxx 4 如何实 ...

  5. HDFS HBase Solr Which one?

    从访问模式角度决策 HDFS 压缩性能最优.扫描速度最快:不支持随机访问,仅支持昂贵.复杂的文件查询 HBase适合随机访问 Solr 适合检索需求 HBase访问单个记录的时间为毫秒级别,而HDFS ...

  6. C++正则表达式笔记之wregex

    遍历所有匹配 #include <iostream> #include <regex> using namespace std; int main() { wstring ws ...

  7. 人生苦短之Python类的一二三

    在Python中,类也是以class开头定义的.我们定义一个动物类,它有名字和年龄,在java变量有实例变量和局部变量,方法内的变量是局部变量,类里面的变量是实例变量.那么在Python中的类及其属性 ...

  8. Splay模板(序列终结者)

    我只是一个存模板的,详细的请看这里http://blog.csdn.net/whai362/article/details/47298133 题目链接:http://www.codevs.cn/pro ...

  9. MAC 安装phantomjs

    step1:下载压缩包http://phantomjs.org/ step2:解压缩,我是解压缩到/Users/gxy/software step3:写入配置路径,vi ~/.bash_profile ...

  10. python中的不可变类型和可变类型

    在python中整形,字符串,元组是不可变类型,而列表和字典都是可变类型. 对于不可变类型进行重新赋值,相当于是用以前的变量名重新指向了新的地址,这个地址中存的变量值就是重新的赋值 通过python中 ...