蓝桥杯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号位各一名球员,组成球队的首发阵容.每位球员担 ...
随机推荐
- WPF中的数据绑定Data Binding使用小结
完整的数据绑定的语法说明可以在这里查看: http://www.nbdtech.com/Free/WpfBinding.pdf MSDN资料: Data Binding: Part 1 http:// ...
- EasyDarwin手机直播转发快速显示问题之音频处理过程
前言 在我们前面一篇<EasyDarwin手机直播是如何实现的快速显示视频的方法>中,我们描述到了EasyDarwin流媒体服务器端是如何对视频H.264进行缓冲,再以最快的方式将最新的视 ...
- 针对Web.config敏感信息加密
cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 ==在appSettings节点上添加== <configProtectedData> & ...
- c/c++标准库中的文件操作总结
1 stdio.h是c标准库中的标准输入输出库 2 在c++中调用的方法 直接调用即可,但是最好在函数名前面加上::,以示区分类的内部函数和c标准库函数. 3 c标准输入输出库的使用 3.1 核心结构 ...
- Android Button Maker(在线生成android shape xml文件的工具),真方便!
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/scry5566/article/details/25379275 直接上地址:http ...
- BZOJ1086 王室联邦 —— 树分块
题目链接:https://vjudge.net/problem/HYSBZ-1086 1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 16 ...
- Redis使用经验之谈
应用场景 保存用户喜欢的商品信息. 类型: Hash, key: usr:${type_id}:${version_id}:${user_id}:${warehouse_id}, field: ${s ...
- dhclient命令
语法:dhclient(选项)(参数) 选项0:指定dhcp客户但监听的端口号-d:总是以前台方式运行程序-q:安静模式,不打印任何错误的提示信息-r:释放ip地址 参数:网络接口:操作的网络接口 示 ...
- Myeclipse项目内容没有报错但是项目上面却有红色叉叉
当src文件夹为空的时候,git是不提交空文件夹的,所以check出来的项目中没有src文件夹,这个时候也会出现此问题.
- Java网络编程InetAddress类
InetAddress用来代表IP地址.一个InetAdress的对象就代表着一个IP地址, getByName(String host):在给定主机名的情况下确定主机的 IP 地址,主机名可以是机器 ...