题意: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. Observer 观察者模式

    简介       观察者模式(Observer),有时又被称为[发布]publish-[订阅]Subscribe模式.模型-视图(View)模式.源-收听者(Listener)模式或从属者模式.在此种 ...

  2. Spring.Net+NHibernate+asp.net mvc + easyui

    毕业4个月的入手项目..前段时间在公司一直做的维护..为了弄明白自己也就跟着写了一个,目前也正在学习:不对的或者是有更好的还请各位赐教. 在学习的过程中主要参考::http://www.cnblogs ...

  3. MySQL+PHP配置 Windows系统IIS版(转)

    1.下载 MySQL下载地址:http://dev.mysql.com/downloads/mysql/5.1.html->Windows (x86, 32-bit), MSI Installe ...

  4. 一段jquery代码,保存

    @CHARSET "UTF-8"; #table_id tbody tr.odd td:hover{ background-color:#93CFE5; } #table_id t ...

  5. Mysql 中和同to_char 一样用法的函数

    STR_TO_DATE() $sql = " SELECT "; $sql .= " m_img,m_content,STR_TO_DATE(m_time,\" ...

  6. birt报表中使用多个数据集。

    这个问题困扰了几天,也没搜到答案,由于工作需要,创建了两个数据集和两个表格,第一个数据集和表格之间没有任何问题.但是第二个数据集拖过去就显示不可用,除非拖到表格外面,当然也就没用了.一朋友说拖一个网格 ...

  7. 关于C#编程中引用与值类型赋值的一些容易犯错的地方

    值类型与引用类型的区别在于:值类型在赋值的时候是拷贝值,引用类型在赋值的时候的拷贝引用.记住这一个原则,我们再来分析一些具体情况: PointStruct pt1 = ,); PointStruct ...

  8. Direct2D 加载位图

    说明: 通过WIC从文件加载位图. 可缩放后加载到内存. 源码: HRESULT LoadImageFormFile( IWICImagingFactory *pWicFactory, ID2D1Re ...

  9. 嵌入式开发(一) Ubuntu12.04下搭建交叉编译环境

    操作系统:Ubuntu12.04 AMD64位 交叉编译环境:arm-Linux gcc版本4.4.3 前言: 首先理解一下交叉编译的意思.我们要给嵌入式设备写应用程序,但是又不能在嵌入式设备上完成所 ...

  10. Linux makefile 教程 非常详细,且易懂(转)

    转自:http://blog.chinaunix.net/uid-27717694-id-3696246.html 原文地址:Linux makefile 教程 非常详细,且易懂 作者:Deem_pa ...