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. Nuxt使用Vuex

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 基础知识这里不再重述,学习的话请自行到官网 ...

  2. 我的Android进阶之旅------>解决Bug:打开eclipse报错,发现了以元素 'd:skin' 开头的无效内容。此处不应含有子元素。

    今天来打开Eclipse 报错了,错误信息如下: [2015-08-01 09:07:43 - Android SDK] Error when loading the SDK: Error: Erro ...

  3. Android怎样在http头信息里设置參数

    在使用http请求server时经常要传递一些參数给server.如IMEI号.平台号.渠道号.client的版本等一些通用信息,像这些參数我们没有必要每次都拼在url后,我们能够统一加入到http头 ...

  4. Android:日常学习笔记(9)———探究广播机制

    Android:日常学习笔记(9)———探究广播机制 引入广播机制 Andorid广播机制 广播是任何应用均可接收的消息.系统将针对系统事件(例如:系统启动或设备开始充电时)传递各种广播.通过将 In ...

  5. linux常用技巧(资料)

    Linux中查看程序安装位置 如果是rpm的安装,用rpm -ql如果是一般安装 用 whereis 或者 find find /usr -name catalina.out======== 如何查看 ...

  6. $Android启动界面(Splash)的两种实现方法

    (一)用2个Activity实现 用Handler对象的postDelayed方法来实现延迟跳转的目的. 补充:Handler的常用方法: // 立即执行Runnable对象 public final ...

  7. java经典30笔试题

    1. 下面哪些是Thread类的方法() A start()       B run()       C exit()       D getPriority() 答案:ABD 解析:看Java AP ...

  8. 五、golang实现排序

    实现排序: 1.实现一个冒泡排序 2.实现一个选择排序 3.实现一个插入排序 4.实现一个快速排序 冒泡排序 package main import( "fmt" ) func b ...

  9. 使用concurrent.futures和ProcessPoolExecutor来替代线程和进程

    concurrent.futures和ProcessPoolExecutor这两个类实现的借口分别在不同的线程或进程中执行可调用的对象,这两个类在内部维护者一个工作线程或进程池,以及要执行的队列,这两 ...

  10. 使用fastboot刷机流程【转】

    本文转载自:http://www.voidcn.com/blog/Qidi_Huang/article/p-6236224.html [准备工作] 首先需要准备好刷机包,可以是自己编译的,也可以是从别 ...