求一条蛇到(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. Centos安装Kafka集群

    kafka是LinkedIn开发并开源的一个分布式MQ系统,现在是Apache的一个孵化项目.在它的主页描述kafka为一个高吞吐量的分布式(能 将消息分散到不同的节点上)MQ.在这片博文中,作者简单 ...

  2. Storm:最火的流式处理框架

    伴随着信息科技日新月异的发展,信息呈现出爆发式的膨胀,人们获取信息的途径也更加多样.更加便捷,同时对于信息的时效性要求也越来越高.举个搜索场景中的例子,当一个卖家发布了一条宝贝信息时,他希望的当然是这 ...

  3. for while (list each)的用法

    each是返回数组 指针当前指向的 元素的 索引和值: 索引有四个值: 0, 1, key, value. 0和key是一样的, 1和value是一样的 但是each只是将数组指针 向前移动 一步, ...

  4. Memcached 简介、安装和基本使用

    本章包括内容: 一.Memcached是什么.能干什么.特点; 二.在Centos7上安装Memcached 三.Memcached启动.简单操作.关闭------------------------ ...

  5. Ionic 常见问题及解决方案

    前言 Ionic是目前较为流行的Hybird App解决方案,在Ionic开发过程中会遇到很多常见的开发问题,本文尝试对这些问题给出解决方案. 一些常识与技巧 list 有延迟,可以在ion-cont ...

  6. plink远程连接服务器进行编译

    脚本命令: echo y|D:\remote_link\plink  -l  user  -pw password  172.16.0.101 "export LANG=en_US;cd / ...

  7. springmvc之DispatcherServlet

    1.作用:DispatcherServlet是前置控制器,配置在web.xml(因为DispatcherServlet是一个servelet)文件中的.拦截匹配的请求,Servlet拦截匹配规则要自已 ...

  8. 分享一个c#t的网页抓取类

    using System; using System.Collections.Generic; using System.Web; using System.Text; using System.Ne ...

  9. CSS使用自定义光标样式-遁地龙卷风

    测试环境是chrome浏览器 Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357. ...

  10. leetcode 33. Search in Rotated Sorted Array

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...