求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些


POJ1324(ZOJ1361)-Holedox Moving

  题意:一条已知初始状态的蛇,求其到(1,1)的最短路长

  题解:开始做的时候用BFS暴力做了一次,结果RE了,后来看了其他的题解和discuss才转向状态压缩。也看到有人用A*做出来了。

    现在简要介绍一下状态压缩的思路:

      由于蛇身最长只有8,可以利用两条相邻蛇身坐标确定其相对方向(四个方向),两位二进制可以表示

      这样 一个蛇头坐标+14位二进制数 就可以确定一个蛇身状态

      而后状态重复则可以进行剪枝,这是一种很好的优化。

    这里我用一个方向数组mov[4][2]简化代码,而且不需要自己考虑太多方向的先后顺序及分支。

 //蛇的移动-求达到终点的最短路长
//BFS+状态压缩
//两位二进制(4个方向)记录后一个蛇身相对前一个的位置,以此将蛇身记录为数值
//POJ:Time: 1297Ms Memory: 25440K
//ZOJ:Time: 350Ms Memory: 31388K
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAX = ;
const int MAXN = ;
const int MAXLEN = << + ;
struct Snake{
int x, y;
}snake[];
struct State {
Snake h; //头部坐标
unsigned hash;
int step;
}s[MAXN];
int row, col, len;
bool map[MAX][MAX]; //是否存在障碍
bool v[MAX][MAX][MAXLEN]; //状态记录
int mov[][] = { {,}, {-,}, {,}, {,-} };
int get_next_hash(int hash, Snake pre, Snake next)
{
const int INF = ( << ((len - ) << )) - ;
int dx = pre.x - next.x;
int dy = pre.y - next.y;
for (int i = ; i < ; i++)
{
if (mov[i][] == dx && mov[i][] == dy)
{
hash <<= ;
hash &= INF;
hash |= i;
break;
}
}
return hash;
}
/*是否撞到自己或障碍*/
bool judge(State cur, Snake t)
{
if (t.x > && t.x <= row && t.y > && t.y <= col && !map[t.x][t.y])
{
for (int i = ; i < len; i++)
{
int key = ( << ) - ;
key &= cur.hash;
cur.hash >>= ;
cur.h.x += mov[key][];
cur.h.y += mov[key][];
if (cur.h.x == t.x && cur.h.y == t.y) //撞到了
return false;
}
return true;
}
return false;
}
void bfs()
{
int front = , tail = ;
s[].step = ;
if (s[].h.x == && s[].h.y == )
{
printf("0\n");
return;
}
while (front < tail)
{
for (int i = ; i < ; i++)
{
Snake t;
t.x = s[front].h.x + mov[i][];
t.y = s[front].h.y + mov[i][];
if (t.x == && t.y == )
{
printf("%d\n", s[front].step + );
return;
}
if (judge(s[front], t))
{
s[tail].hash = get_next_hash(s[front].hash, s[front].h, t);
if (!v[t.x][t.y][s[tail].hash])
{
v[t.x][t.y][s[tail].hash] = true;
s[tail].h = t;
s[tail].step = s[front].step + ;
tail++;
}
}
}
front++;
}
printf("-1\n");
}
//初始化蛇的开始位置
void init_snake()
{
s[].h = snake[];
s[].hash = ;
for (int i = len - ; i > ; i--)
s[].hash = get_next_hash(s[].hash, snake[i], snake[i - ]);
v[s[].h.x][s[].h.y][s[].hash] = true;
}
int main()
{
int counter = ;
while (scanf("%d%d%d", &row, &col, &len), row && col && len)
{
memset(map, false, sizeof(map));
memset(v, false, sizeof(v));
for (int i = ; i < len; i++)
scanf("%d%d", &snake[i].x, &snake[i].y);
int m, x, y;
scanf("%d", &m);
for (int i = ; i < m; i++)
{
scanf("%d%d", &x, &y);
map[x][y] = true;
}
init_snake();
printf("Case %d: ", ++counter);
bfs();
}
return ;
}

ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))的更多相关文章

  1. ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))

    祝大家新年快乐,相信在新的一年里一定有我们自己的梦! 这是一个简化的魔板问题,只需输出步骤即可. 玩具(Toy) 描述 ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具. 该玩具酷似魔方, ...

  2. BFS+状态压缩 hdu-1885-Key Task

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1885 题目意思: 给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应 ...

  3. HDU1429+bfs+状态压缩

    bfs+状态压缩思路:用2进制表示每个钥匙是否已经被找到.. /* bfs+状态压缩 思路:用2进制表示每个钥匙是否已经被找到. */ #include<algorithm> #inclu ...

  4. poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)

    Description Flip game squares. One side of each piece is white and the other one is black and each p ...

  5. BFS+状态压缩 HDU1429

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  6. hdoj 5094 Maze 【BFS + 状态压缩】 【好多坑】

    Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Sub ...

  7. HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)

    题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP ...

  8. UVALive 3956 Key Task (bfs+状态压缩)

    Key Task 题目链接: http://acm.hust.edu.cn/vjudge/contest/129733#problem/D Description The Czech Technica ...

  9. HDOJ 1429 胜利大逃亡(续) (bfs+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 思路分析:题目要求找出最短的逃亡路径,但是与一般的问题不同,该问题增加了门与钥匙约束条件: 考虑 ...

随机推荐

  1. 使用Struts 2框架实现文件下载

    从服务器发送一个文件到浏览器需要以下几个步骤 把HTTP响应里的ContentType标头设置为被下载文件的内容类型.ContentType标头的作用是表明数据包里的数据是什么类型, 它由一个多媒体类 ...

  2. 利用SoapUI 测试web service的方法介绍

    1. 简介 SoapUI是用java开发的测试web service的工具. 2. 安装 2.1. 下载地址 http://www.soapui.org/ 2.2. 安装 By downloading ...

  3. Mysql函数:Last_insert_id()语法讲解

    Mysql函数可以实现许多我们需要的功能,下面介绍的Mysql函数Last_insert_id()就是其中之一,希望对您学习Mysql函数能有所帮助. 自动返回最后一个INSERT或 UPDATE 查 ...

  4. [MongoDB]增删改查

    摘要 上篇文章学习了mongodb在windows上的安装,以及如何开启mongodb,最后列举了简单的增删改查操作.本篇将继续深入学习一下增删改查. 相关文章 [MongoDB]入门操作 CRUD ...

  5. PHP中spl_autoload_register()函数

    spl_autoload_register — 注册给定的函数作为 __autoload 的实现 官方地址:http://php.net/manual/zh/function.spl-autoload ...

  6. HighCharts日期及数值格式化

    1.函数原型   1 dateFormat(Stringformat,[Numbertime],[Booleancapitalize])::String 2.说明 格式化JavaScript 时间(也 ...

  7. 【Solr】 solr对拼音搜索和拼音首字母搜索的支持

    问:对于拼音和拼音首字母的支持,当你在搜商品的时候,如果想输入拼音和拼音首字母就给出商品的信息,怎么办呢? 实现方式有2种,但是他们其实是对应的.  用lucene实现 1.建索引, 多建一个索引字段 ...

  8. tyvj1614 魔塔魔塔!

    描述 百度noip贴吧管理组开发了一个小游戏,叫魔塔魔塔.虽然把魔塔重复了两次,但其实还只是个魔塔而已,还是简化版的.游戏在一个N*M大小的地图中进行,每一格都是正方形.对于某一格,有若干种可能的状态 ...

  9. Smarty基础

    smarty将php代码和HTML代码分开,形成两个页面,通过在php页面引用smarty配置文件,利用php控制HTML页面显示 1,libs文件夹,放入需要使用的文件夹下面 2,配置文件:init ...

  10. 教你如何删除tomcat服务器的stdout.log文件

    用Tomcat做WEB服务器的人都知道,有个很让人头痛的问题,就是stdout.log日志文件会自动增长,而且增长得很快. 先来看看我的痛处吧,公司有个WEB应用,就是用Tomcat作为服务器的,由于 ...