一、题意:类似于华容道,输入是8个数字,输入虽然是一行,但实际是以两行的方式操作的。0表示空位,别的相邻数字可移动到该位置上。求最少移动步骤得到指定的状态。

二、思路:这题可以用BFS来解决。因为在每一步可以产生两个状态,类似于走迷宫里的移动,不同的是这里的坐标变化是一维的:+1,-1,+4,-4。这里需要注意一点是坐标3不能+1,坐标4不能-1,因为这里是排两行的,所以这个小细节很关键。每个状态可以用字符串和0的坐标0来存储(map),并且可以用改字符串对应的整数来标记该状态是否出现过已达到剪枝的效果。这里用到了几个小技巧:1、int类型和string类型的相互转换  2、map的使用。用map来记录到各个状态的步数。如果用数组来存,会MLE。 3.打表。这个很关键,因为逆向思维来说,初始状态都是“01234567”,所以打表后后面直接查表,效率会高很多,不然会TLE。 4.pair函数的使用。用一个pair类型的队列来记录每一个状态以及这个状态下0的位置。 5.在做坐标交换时,我自定义了一个Change函数,也可以用系统自带的swap函数,更简洁。

三、代码:

#include"iostream"
#include"stdio.h"
#include"queue"
#include"string.h"
#include"map"
#include"sstream"
#include"stdlib.h"
using namespace std; typedef pair<string,int> P; int inputSample[10];
string inputString;
map<string,int>state; string Int2String(int &a)
{
ostringstream oss;
oss<<a;
return oss.str();
} bool Judge(int x)
{
if(x>=0&&x<8) return true;
return false;
} string Change(int a,int b,string str)
{
char tmp=str[a];
str[a]=str[b];
str[b]=tmp; return str;
} int Bfs()
{
queue<P> que; que.push(P("01234567",0));
while(que.size())
{
P p=que.front();que.pop(); int dir[4]={1,-1,4,-4}; for(int i=0;i<4;i++)
{
if(p.second==3&&dir[i]==1) continue;
if(p.second==4&&dir[i]==-1) continue;
int nx=p.second+dir[i];
if(Judge(nx))
{
string str=Change(p.second,nx,p.first);
if(state.find(str)==state.end())
{
state[str]=state[p.first]+1;
que.push(P(str,nx));
}
}
}
}
return -1;
} int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
state["01234567"]=0;
Bfs();
while(scanf("%d",&inputSample[0])==1)
{
for(int i=1;i<8;i++)
cin>>inputSample[i];
inputString=""; for(int i=0;i<8;i++)
{
inputString+=Int2String(inputSample[i]);
} cout<<state[inputString]<<endl;
}
return 0;
}

  

  

aoj0121的更多相关文章

  1. 《挑战程序设计竞赛》2.1 广度优先搜索 AOJ0558 POJ3669 AOJ0121

    AOJ0558 原文链接: AOJ0558 题意: 在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪.有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪.老鼠有一个体力值,初始时为1,每 ...

  2. 挑战程序2.1.5 穷竭搜索>>宽度优先搜索

    先对比一下DFS和BFS         深度优先搜索DFS                                   宽度优先搜索BFS 明显可以看出搜索顺序不同. DFS是搜索单条路径到 ...

  3. poj1077 Eight【爆搜+Hash(脸题-_-b)】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298840.html   ---by 墨染之樱花 题目链接:http://poj.org/pr ...

随机推荐

  1. Part9---代码搬移不可少

    1.回顾ARM启动流程就可知道需要执行代码搬移 2.代码搬移 1)起点:NAND FLASH,今天的起点是SRAM垫脚石.为什么?因为我们要从nandflash取搬移数据需要先对其进行初始化,二而我们 ...

  2. 升级Ubuntu 12.04下的gcc到4.7

    我们知道C++11标准开始支持类内初始化(in-class initializer),Qt creator编译出现error,不支持这个特性,原因在于,Ubuntu12.04默认的是使用gcc4.6, ...

  3. 做ETL的时候用到的数据同步更新代码

    这里是用的从一个库同步到另一个库,代码如下 private void IncrementalSyncUpdate(string fromConn, string toConn, Dictionary& ...

  4. SurfaceView和SurfaceHolder的基本用法

    仅做记录使用,新手也可以来看看,怎么得到一个surfaceholder. 1.在xml文件中增加一个surfaceView控件. <SurfaceView android:layout_widt ...

  5. Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'blog.t_blog.addTime' which is not functi

    sql报错: Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #1 of SELECT ...

  6. HTML中&nbsp; &ensp; &emsp; &thinsp;等6种空白空格

  7. jvm学习笔记之对象详解

    一.对象的组成 对象头(Header): 运行时数据:存储对象运行时的数据,如哈希码.GC分代年龄.锁状态标志.线程持有的锁.偏向线程ID.偏向时间戳等,这部分数据官方成为“Mark Word”,它的 ...

  8. 通过html()的方法获取文本内容, form表单组件显示的值与获取到的值不一致的问题

    我在通过 html()获取对应节点的内容,发现一个问题,获取到的 form表单组件的内容值是初始加载的值,而不是经过用户修改后的值.例如页面加载时组件<input type="text ...

  9. 题解 P1632 点的移动

    P1632 点的移动 题目描述 平面上有N个整数坐标点.如果将点(x0,y0)移动到(x1,y1),则需要的代价为|x0-x1|+|y0-y1|.求使得K(K=1,-,N)个点在同一位置上最少需要的代 ...

  10. bit、Byte、bps、Bps、pps、Gbps的单位的说明及换算

    一.bit与Byte区别 1. bit(比特) 是电脑记忆体的最小单元,在二进制计算机中,每一比特代表0或1的数位信号. 2. Byte(单位字节) 一般表示存储介质大小的单位,数字.字母和特殊符号占 ...