Holedox Moving
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 17042   Accepted: 4065

Description

During winter, the most hungry and severe time, Holedox sleeps in its lair. When spring comes, Holedox wakes up, moves to the exit of its lair, comes out, and begins its new life.
Holedox is a special snake, but its body is not very long. Its lair
is like a maze and can be imagined as a rectangle with n*m squares. Each
square is either a stone or a vacant place, and only vacant places
allow Holedox to move in. Using ordered pair of row and column number of
the lair, the square of exit located at (1,1).

Holedox's body, whose length is L, can be represented block by
block. And let B1(r1,c1) B2(r2,c2) .. BL(rL,cL) denote its L length
body, where Bi is adjacent to Bi+1 in the lair for 1 <= i <=L-1,
and B1 is its head, BL is its tail.

To move in the lair, Holedox chooses an adjacent vacant square of
its head, which is neither a stone nor occupied by its body. Then it
moves the head into the vacant square, and at the same time, each other
block of its body is moved into the square occupied by the corresponding
previous block.

For example, in the Figure 2, at the beginning the body of Holedox
can be represented as B1(4,1) B2(4,2) B3(3,2)B4(3,1). During the next
step, observing that B1'(5,1) is the only square that the head can be
moved into, Holedox moves its head into B1'(5,1), then moves B2 into B1,
B3 into B2, and B4 into B3. Thus after one step, the body of Holedox
locates in B1(5,1)B2(4,1)B3(4,2) B4(3,2) (see the Figure 3).

Given the map of the lair and the original location of each block of
Holedox's body, your task is to write a program to tell the minimal
number of steps that Holedox has to take to move its head to reach the
square of exit (1,1).

Input

The
input consists of several test cases. The first line of each case
contains three integers n, m (1<=n, m<=20) and L (2<=L<=8),
representing the number of rows in the lair, the number of columns in
the lair and the body length of Holedox, respectively. The next L lines
contain a pair of row and column number each, indicating the original
position of each block of Holedox's body, from B1(r1,c1) to BL(rL,cL)
orderly, where 1<=ri<=n, and 1<=ci<=m,1<=i<=L. The
next line contains an integer K, representing the number of squares of
stones in the lair. The following K lines contain a pair of row and
column number each, indicating the location of each square of stone.
Then a blank line follows to separate the cases.

The input is terminated by a line with three zeros.

Note: Bi is always adjacent to Bi+1 (1<=i<=L-1) and exit square (1,1) will never be a stone.

Output

For
each test case output one line containing the test case number followed
by the minimal number of steps Holedox has to take. "-1" means no
solution for that case.

Sample Input

5 6 4
4 1
4 2
3 2
3 1
3
2 3
3 3
3 4 4 4 4
2 3
1 3
1 4
2 4
4 2 1
2 2
3 4
4 2 0 0 0

Sample Output

Case 1: 9
Case 2: -1

Hint

In the above sample case, the head of Holedox can follows (4,1)->(5,1)->(5,2)->(5,3)->(4,3)->(4,2)->(4,1)->(3,1)->(2,1)->(1,1) to reach the square of exit with minimal number of step, which is nine.

Source

 
    bfs,难点在于标记数组的表示,如何表示当前蛇的状态,有个很巧妙的方法是利用位运算进行状压,只要知道蛇头的位置以及每一部分之间的关系(即up,down,left,right)我们就可以表示出蛇的状态,最长有7个身长(不包括头),用0,1,2,3表示四个方向每个数占两位最多14位所以内存可以接受。只要处理好状压的蛇身基本就能A了。注意不能走到石头处和当前蛇身处。跑了1700ms。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int N,M,L,K,all;
struct xy{int x,y;}P[];
struct node{int x,y,bs,has;};
bool vis[][][<<];
bool sto[][];
int fx[][]={-,,,,,-,,};
int ldx[]={,,,};
bool check(node t,int dx,int dy)
{
int x=t.x,y=t.y;
for(int i=;i<=L;++i)
{
int tt=;
if(t.has&) tt+=;t.has>>=;
if(t.has&) tt+=;t.has>>=;
x=x+fx[tt][];
y=y+fx[tt][];
if(x==dx&&y==dy) return ;
}
return ;
}
void bfs(node st)
{
memset(vis,,sizeof(vis));
queue<node>q;
q.push(st);
while(!q.empty()){
node t=q.front();q.pop();
if(vis[t.x][t.y][t.has]) continue;
vis[t.x][t.y][t.has]=;
if(t.x==&&t.y==){cout<<t.bs<<endl;return;}
for(int i=;i<;++i)
{
node _t=t;
int dx=_t.x+fx[i][];
int dy=_t.y+fx[i][];
if(dx<||dy<||dx>N||dy>M||sto[dx][dy]||!check(_t,dx,dy)) continue;
int has=(_t.has<<)&(all)|(ldx[i]);
_t.has=has;
_t.bs++;
_t.x=dx;
_t.y=dy;
if(vis[dx][dy][has]) continue;
q.push(_t);
}
}
puts("-1");
}
int main()
{
int i,j,k=;
while(cin>>N>>M>>L){
if(N==&&M==&&L==) break;
memset(sto,,sizeof(sto));
for(i=;i<=L;++i) scanf("%d%d",&P[i].x,&P[i].y);
scanf("%d",&K);
for(i=;i<=K;++i)
{
int o,p;
scanf("%d%d",&o,&p);
sto[o][p]=;
}
printf("Case %d: ",++k);
all=(<<((L-)*))-;
node st;
st.x=P[].x;
st.y=P[].y;
st.bs=;
st.has=;
for(i=;i<=L;++i)
{
for(j=;j<;++j)
{
int dx=P[i-].x+fx[j][];
int dy=P[i-].y+fx[j][];
if(dx==P[i].x&&dy==P[i].y){
st.has=st.has|(j<<((i-)*));
}
}
}
bfs(st);
}
return ;
}

poj 1324 状态压缩+bfs的更多相关文章

  1. 胜利大逃亡(续)(状态压缩bfs)

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

  2. POJ - 1324 Holedox Moving (状态压缩+BFS/A*)

    题目链接 有一个n*m(1<=n,m<=20)的网格图,图中有k堵墙和有一条长度为L(L<=8)的蛇,蛇在移动的过程中不能碰到自己的身体.求蛇移动到点(1,1)所需的最小步数. 显然 ...

  3. POJ 1753 Flip Game (状态压缩 bfs+位运算)

    Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...

  4. POJ 3411 Paid Roads (状态压缩+BFS)

    题意:有n座城市和m(1<=n,m<=10)条路.现在要从城市1到城市n.有些路是要收费的,从a城市到b城市,如果之前到过c城市,那么只要付P的钱, 如果没有去过就付R的钱.求的是最少要花 ...

  5. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

  6. 【HDU - 1429】胜利大逃亡(续) (高级搜索)【状态压缩+BFS】

    Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)…… 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方.刚开 ...

  7. HDU 5025 Saving Tang Monk 【状态压缩BFS】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Time Limit: 2000/1000 MS (Java/O ...

  8. poj 3254(状态压缩+动态规划)

    http://poj.org/problem?id=3254 题意:有一个n*m的农场(01矩阵),其中1表示种了草可以放牛,0表示没种草不能放牛,并且如果某个地方放了牛,它的上下左右四个方向都不能放 ...

  9. 「hdu 4845 」拯救大兵瑞恩 [CTSC 1999](状态压缩bfs & 分层图思想)

    首先关于分层图思想详见2004的这个论文 https://wenku.baidu.com/view/dc57f205cc175527072208ad.html 这道题可以用状态压缩,我们对于每一把钥匙 ...

随机推荐

  1. MySQL中阻塞

    因为不同锁之间的兼容性关系,在有些时刻一个事务中的锁需要等待另一个事务中的锁释放它占有的资源,这就是阻塞.阻塞不是一件坏事,是为了保证事务可以并发并且正常的运行 在InnoDB存储引擎中,参数inno ...

  2. 我的Java开发学习之旅------>二进制、八进制、十进制、十六进制之间转换

    一. 十进制与二进制之间的转换  (1) 十进制转换为二进制,分为整数部分和小数部分  ① 整数部分  方法:除2取余法,即每次将整数部分除以2,余数为该位权上的数,而商继续除以2,余数又为上一个位权 ...

  3. nodejs koa2 获取get值和post值,提交表单

    // 获取get值 router.get('/b', async(ctx, next) => { ctx.state = { title: 'Koa2', name: '小明-list' } l ...

  4. (1)sql server 同网段复制

    转自:https://blog.csdn.net/hliq5399/article/details/51678774(文末有复制系列文章链接) 一.背景 在复制的运用场景中,事务发布是使用最为广泛的, ...

  5. spring tiles界面为空白

    Caused by: org.apache.jasper.JasperException: /WEB-INF/views/admin_template.jsp(3,62) Unable to read ...

  6. Android:日常学习笔记(7)———探究UI开发(4)

    Android:日常学习笔记(7)———探究UI开发(4) UI概述  View 和 ViewGrou Android 应用中的所有用户界面元素都是使用 View 和 ViewGroup 对象构建而成 ...

  7. ES6 随记(3.1)-- 字符串的拓展

    上一章请见: 1. ES6 随记(1)-- let 与 const 2. ES6 随记(2)-- 解构赋值 4. 拓展 a. 字符串的拓展 有些字符需要 4 个字节储存,比如 \uD83D\uDE80 ...

  8. 【Flask】Sqlalchemy join

    ### join:1. join分为left join(左外连接)和right join(右外连接)以及内连接(等值连接).2. 参考的网页:http://www.jb51.net/article/1 ...

  9. JS以指定格式获取当前日期

    //获取当前时间,格式YYYY-MM-DD function getNowFormatDate() { var date = new Date(); var seperator1 = "-& ...

  10. get_class_methods--返回由类的方法名组成的数组

    get_class_methods--返回由类的方法名组成的数组 array get_class_methods ( mixed $class_name ) 返回由类的方法名组成的数组. <?p ...