一、题意:类似于华容道,输入是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. GO程序设计2——面向过程基础知识

    1 简介 GO语言google开发的新语言.有如下特性: 自动垃圾回收.更丰富的内置数据类型.函数多返回值.错误处理.匿名函数和闭包.类型和接口.并发编程.反射.多语言混合编程 package mai ...

  2. hdu 4279 Number(G++提交)

    打表找规律: #include<stdio.h> #include<math.h> #define N 250 bool judge(int i,int j) { ;k< ...

  3. c++基础之引用reference

    1.何为引用 简单来说就是,比如你换了个新名字,用新名字叫你,你也会答应 2.引用vs指针 -引用没有null,好比你说你换了个新名字,但是新名字是啥总得有点东西 -一旦引用被初始化后就不可以指到另外 ...

  4. 转:[web]javascript 增加表單的input

    利用javascript增加form的input 這是js的部份 //用來區分不同input的name var element_count = 0; function add_element(obj) ...

  5. WPF 控件库——可拖动选项卡的TabControl

    WPF 控件库系列博文地址: WPF 控件库——仿制Chrome的ColorPicker WPF 控件库——仿制Windows10的进度条 WPF 控件库——轮播控件 WPF 控件库——带有惯性的Sc ...

  6. .Net Core 项目部署IIS简单步骤

    1.新建一个解决方案: 我习惯会把运行文件移至一级目录 然后清除CoreTest 文件夹里面的文件 2.在解决方案中新建一个项目 点击确认有,这里有几种选择类型,我一般选择空类型(这里需要注意一下,空 ...

  7. MSSQL中数据库对象类型解释

    public string GetObjectTypeName(object oType) { switch (oType+"") { case "U": re ...

  8. fwrite()

    注:fwrite(),fread -可对数据块读写,且数据为二进制,文本下查看为乱码,文件的打开方式为 “b*” 实例: 写入二进制数据 for (int i = 0; i < SN; i++) ...

  9. React杂篇(1) -- 打包发布注意事项

    打包后资源路径 问题:直接打包会出现一下情况: 方式一: package.json文件下加入homepage字段 { "name": "wap-v2", &qu ...

  10. nginx负载均衡tomcat和配置ssl

    目录 tomcat 组件功能 engine host context connector service server valve logger realm UserDatabaseRealm 工作流 ...