题意:7数码问题。在2×4的棋盘上,摆有7个棋子,每个棋子上标有1至7的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格(用0表示),与空格相邻(上下左右)的棋子可以移到空格中,该棋子原先位置成为空格。给出一个初始状态(保证可以转移到最终状态),找出一种从初始状态转变成给定最终状态的移动棋子步数最少的移动步骤。

输入:多组输入,每组8个数,表示初始状态前四个数为第一行从左到右,后四个数为第二行从左到右。

输出:至少需要多少步可以从输入状态到达最终状态(0 1 2 3 4 5 6 7)

(题意翻译参考自http://bbs.byr.cn/#!article/ACM_ICPC/73337?au=Milrivel)

(图1)

  (图2)

  (图3)

分析:

乍一看这题没从入手,但只要采取逆向思维,还是可以用广度优先搜索解决。先不考虑如何用最小步数从输入状态到达最终状态,所有结果的最终状态都是(01234567),那么反过来想,只要求出最终状态到达所有结果时的最小步数并记录下来,接下来就是查表了。0表示空位置,对空位置周围的格子采用广度优先的方式移动到0,并记录下最小步数的结果即可。如上图所示,图1,可以选择让7移动过来变成图2,也可以选择让2移动过来变成图3。我们要做的只不过是不断重复这种选择,直至穷举所有情况并记录结果。

我主要是用一个map<string, int>来表示(01234567)到string 的最小步数int,只要当前结果还不存在,就加入map,必然能够穷尽状态。另外,在移动格子问题上,因为我采用string来表示当前状态,那么移动方向上下左右分别就是当前位置-4, +4, -1, +1。需要注意的是,位置3不能移动到位置4.

 #include <iostream>
#include <queue>
#include <map>
#include <string>
#include <algorithm> using namespace std; typedef pair<string, int> P; const int INF = ; //输入
string a; //移动方向
int op[] = {-, , -, }; map<string, int> dp; //保存从string变到"01234567"的int //计算从"01234567"转换到其他序列所需的最小步数
void bfs(){
//初始化
queue<P> que;
que.push(P("", ));
dp[""] = ;
//宽度优先搜索
while(!que.empty()){
P p = que.front();
que.pop();
string s = p.first;
int cur = p.second;
for(int i = ; i < ; i ++){
//构造下一次交换
int next = cur + op[i];
string str = s;
swap(str[cur], str[next]);
map<string, int>::iterator it = dp.find(str);
//判断是否可移动以及是否访问过
if( <= next && next <
&& !(cur == && next == ) && !(cur == && next == )
&& it == dp.end()){ que.push(P(str, next));
dp[str] = dp[s] + ;
}
}
}
} void solve(){
//删除空格
a.erase(remove(a.begin(), a.end(), ' '), a.end());
cout<<dp[a]<<endl;
} int main(int argc, char const *argv[]){
//先逆向构造所有情况,后直接读取输入用例的结果
bfs();
while(getline(cin, a)){
solve();
}
return ;
}

AOJ 0121 广度优先搜索的更多相关文章

  1. AOJ 0558 广度优先搜索

    题意:在 H * W 的地图里有 N 个工厂,每个工厂分别生产硬度为1-N 的奶酪,有一只老鼠准备把所有奶酪都吃完.老鼠的初始体力值为1,每吃一个奶酪体力值加 1.已知老鼠不能吃硬度大于当前体力值的奶 ...

  2. AOJ 0121: Seven Puzzle【BFS】

    From: AOJ 0121 思路:与前几题的bfs不同,这次的bfs没有明确的移动对象,看似任意一个数都可以当成对象移动.这时我们只需要抓住一个格子就行,比如我们把0作为移动对象,那么0在地图中漫游 ...

  3. 图的广度优先搜索(BFS)

    把以前写过的图的广度优先搜索分享给大家(C语言版) #include<stdio.h> #include<stdlib.h> #define MAX_VERTEX_NUM 20 ...

  4. 广度优先搜索(BFS)

    定义 维基百科:https://en.wikipedia.org/wiki/Breadth-first_search 给定图G=(V,E)和一个可识别的源结点s,广度优先搜索对图G中的边进行系统性的探 ...

  5. 总结A*,Dijkstra,广度优先搜索,深度优先搜索的复杂度比较

    广度优先搜索(BFS) 1.将头结点放入队列Q中 2.while Q!=空 u出队 遍历u的邻接表中的每个节点v 将v插入队列中 当使用无向图的邻接表时,复杂度为O(V^2) 当使用有向图的邻接表时, ...

  6. AOJ 0121: Seven Puzzle (BFS DP STL 逆向推理)(转载)

    转载自:  http://m.blog.csdn.net/blog/Enjoying_Science/42008801 题目链接:http://acm.hust.edu.cn/vjudge/probl ...

  7. ACM题目————图的广度优先搜索

    题目描述 图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接 点的邻接点.如此进行下去,直到所有的结点都访问为止.在该题中,假定所有的结 ...

  8. SDUT 2141 【TEST】数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历

    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  9. HDU 1312 Red and Black DFS(深度优先搜索) 和 BFS(广度优先搜索)

    Red and Black Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...

随机推荐

  1. Apache MINA NioSocketAcceptor类的实现

    NioSocketAcceptor 继承AbstractPollingIoAcceptor,实现SocketAcceptor接口 public final class NioSocketAccepto ...

  2. python 之路,Day11 (下)- sqlalchemy ORM

    python 之路,Day11 - sqlalchemy ORM   本节内容 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业 1. ORM ...

  3. 制作Android Demo GIF:程序演示效果GIF图录制

    [转] 制作Android Demo GIF:程序演示效果GIF图录制   在平时写博客或者分享自己写的程序效果的时候经常需要做成GIF图,以下就是介绍几种常用的GIF录制方法: 一.录制工具 1.( ...

  4. codevs 1213 解的个数(我去年打了个表 - -)

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; int T,x ...

  5. dir()函数:罗列出参数所有的功能列表

    #coding=utf-8import sysprint dir(sys)#罗列出参数中所有的功能列表sys.__doc__#调用参数中的函数 #dir()函数扩展展详解python中dir()函数不 ...

  6. JY02-HTML/CSS-京东01 定位是很粗暴的页面布局方法

    1.学习重点 1. 独立完成开发前的准备工作 1.1 配置开发环境 已使用sublime,webstorm,,,vscode,ato,Hbuilder 1.2 建立项目文件 项目文件名/ css.js ...

  7. 突然想写点东西,关于web新人的。采用问答方式

    我自己是会计专业,转行自学web的,学习有一两年了,也还是新人一个,只不过不是那种超级“新”的,所以有什么话说得不对,请轻喷.欢迎大家来和我交流. 1.我能不能转行学web? 能不能学web这个不是别 ...

  8. css.day.05.eg

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. AIDL跨进程通信

    Android跨进程通信会用到AIDL,当然跨进程通信不一定要用AIDL,像广播也是可以的,当然这里用到AIDL相对比较安全一些: AIDL允许传递基本数据类型(Java 的原生类型如int/long ...

  10. Linux命令--用户用户组管理

    新增用户组 : groupadd groupadd [-g GID] 组名 不加-g 则按照系统默认的gid创建组,跟用户一样,gid也是从500开始的 修改用户组信息 : groupmod grou ...