蓝桥杯T42(八数码问题)
题目链接: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(八数码问题)的更多相关文章
- 第八届蓝桥杯JavaB组省赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.购物单 题目描述 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推 ...
- Java实现第八届蓝桥杯购物单
购物单 题目描述 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打 ...
- Java实现 蓝桥杯 算法提高 八数码(BFS)
试题 算法提高 八数码 问题描述 RXY八数码 输入格式 输入两个33表格 第一个为目标表格 第二个为检索表格 输出格式 输出步数 样例输入 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 ...
- 第四届蓝桥杯 c/c++真题
第四届蓝桥杯 c/c++真题 <1>高斯日记 问题 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们 ...
- 【蓝桥杯单片机02】LED的基本控制
[蓝桥杯单片机02]LED的基本控制 广东职业技术学院 欧浩源 在CT107D单片机综合训练平台实现LED的基本控制和其他单片机开发平台不一样,不单单是控制几个LED实现跑马灯这么简单.因为在这个平 ...
- 2018年第九届蓝桥杯题目(C/C++B组)汇总
第一题 标题:第几天 2000年的1月1日,是那一年的第1天. 那么,2000年的5月4日,是那一年的第几天? 注意:需要提交的是一个整数,不要填写任何多余内容. 解题思路: 1. 判断2月有几天, ...
- 2017第八届蓝桥杯C/C++语言A组
一:题目: 标题:迷宫 X星球的一处迷宫游乐场建在某个小山坡上.它是由10x10相互连通的小房间组成的. 房间的地板上写着一个很大的字母.我们假设玩家是面朝上坡的方向站立,则:L表示走到左边的房间,R ...
- 2016第七届蓝桥杯C/C++语言A组
一:问题: 某君新认识一网友.当问及年龄时,他的网友说:“我的年龄是个2位数,我比儿子大27岁,如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄” 请你计算:网友的年龄一共有多少种可能情况? 提 ...
- 蓝桥杯第十届真题B组(2019年)
2019年第十届蓝桥杯大赛软件类省赛C/C++大学B组# 试题 A:组队# 本题总分:5分[问题描述]作为篮球队教练,你需要从以下名单中选出 1号位至 5号位各一名球员,组成球队的首发阵容.每位球员担 ...
随机推荐
- JS中小数如何转化为百分数并能四舍五入
<script type="text/javascript">//n表示百分数保留的位数 function toPercent(n){ n = n || 2; retu ...
- EasyDarwin开源流媒体云平台中boost Base64编解码后与源长度不匹配的bug
本文转自EasyDarwin团队Alex的博客:http://blog.csdn.net/cai6811376 EasyDarwin云平台中部分协议使用了Base64编码昨晚报文通信的载体.比如在对摄 ...
- 用EasyClient开源项目采集Windows摄像头/麦克风的音视频进行RTSP直播
EasyClient是EasyDarwin开源流媒体团队开发的一款功能丰富的开源PC客户端项目,目前支持Windows.Android版本,后续将支持ios版本,其中Windows版本的EasyCli ...
- csslint
http://csslint.net/ line column title description browserwarning 1 1 Disallow @import @import preven ...
- Möbius strip
en.wikipedia.org/wiki/Möbius_strip http://mechproto.olin.edu/final_projects/average_jo.html Fabricat ...
- 那些让你代码思维和能力有较大的提升Java源码(转)
对于学习J2EE的框架有很大的帮助,代码里使用了各种设计模式.事件机制.Java8语法.代码量也很小,web服务使用Netty作为支持,对HTTP/网络想研究的一定是你的必读品.目前在写 Blade- ...
- eclipse配置SVN
1.设置 maven 工程svn忽略target 最新maven写法忽略的文件,还需忽略target.*/logs. Windows -> Preferences -> Team -> ...
- FFmpeg big changes. ffmpeg 接口的一些改变
Big changes have been made from FFmpeg 0.5.1… Refer to http://cekirdek.pardus.org.tr/~ismail/ffmpeg- ...
- 使用jQuery集成Google翻译
利用jQuery,轻松将google翻译集成到你的web应用中. 1. [代码][JavaScript]代码 1<script src="Scripts/Translator ...
- 物理机装kali复盘
复盘总结 最近把旧电脑想刷成kali的单系统,便下载了最新版本的kali 2018.1 的镜像文件.由此出现了很多问题. 首先在制作启动盘的时候,我用了很多软件,比如Ultriso,rufus,uni ...