题目链接: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. 【windows phone】CollectionViewSource的妙用

    在windows phone中绑定集合数据的时候,有时候需要分层数据,通常需要以主从试图形式显示.通常的方法是将第二个ListBox(主视图)的数据源绑定到第一个ListBox (从视图)的Selec ...

  2. 最新wap手机agent

    名称 agent 铃声格式 和弦数 数据量 删除 LGE-CU8080  LGE-CU8080/1.0 UP.Browser/4.1.26l UP.Link/5.1.2.9  pmd2.0  40   ...

  3. compute the su procedure time with python

    #!/usr/bin/python2.6 import re,datetime file_name='sim.log' file=open(file_name,'r') acnum=[];time_r ...

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

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

  5. slim.flatten——将输入扁平化但保留batch_size,假设第一维是batch

    slim.flatten(inputs,outputs_collections=None,scope=None) (注:import tensorflow.contrib.slim as slim) ...

  6. [原创]Java开发在线打开编辑保存Word文件(支持多浏览器)

    Java调用PageOffice实现在线编辑保存Word文件(以jsp调用为例,支持SSM.SSH.SpringMVC等流行框架) 1. 下载PageOffice开发包:http://www.zhuo ...

  7. nyoj 1279 (河南省第九届ACM比赛 D 题)

    思路:变换一下坐标系新的坐标系就是给定的两条直线,变换之后求 x,y 都严格递增的点的个数的max: 求 x,y 都严格递增的点的个数的max,按照x的从小到大排序,x相同的按照y的从大到小排序然后对 ...

  8. hdu-5003 Osu!(水题)

    题目链接: Osu! time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Prob ...

  9. POJ3624(01背包:滚动 实现)

    Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30417   Accepted: 13576 ...

  10. bzoj4430

    bit+容斥原理 我不会cdq分治只能用这个做法 考虑什么情况下不满足,至少有一个顺序不对就不行了,那么不满足的总有两对属性形成逆序对,那么我们用总方案数*2=n*(n-1)减去不符合的*2再/2就是 ...