蓝桥杯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号位各一名球员,组成球队的首发阵容.每位球员担 ...
随机推荐
- PHP中的面向对象 中的类(class)
2.11 上午讲的是面向对象中的类(class),一个非常抽象的概念, 类里面成员的定义有 public$abc; private$abc(私有变量): protect $abc(受保护的变量): 下 ...
- EasyDarwin云平台:EasyCamera开源摄像机接入海康威视摄像机PS流转ES流
本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376 海康威视使用PS流封装H.264流,EasyDarwin云平台支持ES流.当我们 ...
- SQL 系统表应用
查看link server select DD.System,DD.DB,DD.previous_processing_dte, DD.processing_dte,LS.LinkServerName ...
- win10搭建selendroid测试环境
官网对于搭建selendroid列出如下要求: 就如 Junit 一样,Selendroid 可以在 Mac,Linux 和 Windows 上使用.Java 主打的就是跨平台. Java SDK ( ...
- Vue数据双向绑定探究
前面的啰嗦话,写一点吧,或许就有点用呢 使用过vue的小伙伴都会感觉,哇,这个框架对开发者这么友好,简直都要笑出声了. 确实,使用过vue的框架做开发的人都会感觉到,以前写一大堆操作dom,bom的东 ...
- Understand .sync in Vue
Preface The first time I met .sync modifier, I didn't know it very well. So, I seldom use that. Toda ...
- ubuntu安装ros indigo
版本是14.04.1 一.先配置 1.点击新立得软件包管理器,输入密码exbot123, 2,点击最上面一栏的设置,选择软件源,前四个打勾,后一个不打,把sevice america改成mainsev ...
- 双端队列篇deque SDUT OJ 双向队列
双向队列 Time Limit: 1000MS Memory limit: 65536K 题目描述 想想双向链表……双向队列的定义差不多,也就是说一个队列的队尾同时也是队首:两头都可以做出队,入队的操 ...
- Codeforces Round #173 (Div. 2) E. Sausage Maximization —— 字典树 + 前缀和
题目链接:http://codeforces.com/problemset/problem/282/E E. Sausage Maximization time limit per test 2 se ...
- Zookeeper实现负载均衡原理
先玩个正常的,好玩的socket编程: 服务端: 首先公共的这个Handler: package com.toov5.zkDubbo; import java.io.BufferedReader; i ...