POJ 1324 Holedox Moving (状压BFS)

Time Limit: 5000MS Memory Limit: 65536K

Total Submissions: 18091 Accepted: 4267

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.

题目解析

状压BFS,除了头结点,其他结点用和前一个结点相对位置来记录

代码

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std; const int dx[4] = {0,0,1,-1};
const int dy[4] = {1,-1,0,0};
int n,m,k; int vis[22][22][1<<14];
int stone[22][22];
int ans = -1; //void show(int z)
//{
// for(int i = (k-1)*2-1; i>=0; i--){
// if((1<<i)&z) cout<<"1";
// else cout<<"0";
// }
//} struct Snake
{
int x,y;
int zt;
int t;
}snake;
/*
后一个结点减去前一个结点的值为a b时,记为cd
a b c d
1 0 0 0
-1 0 0 1
0 1 1 0
0 -1 1 1
*/ bool check_fail(Snake s,int nx,int ny)
{
// cout<<"check point "<<s.x<<" "<<s.y<<" ZT";
// show(s.zt);
// cout<<endl;
int prex = s.x;
int prey = s.y; int w = (1<<((k-2)*2));
int t = k - 1;
while(t--){
int cx = (s.zt/w)/2;
int cy = (s.zt/w)%2;
s.zt%=w; // cout<<"cx "<<cx<<" cy "<<cy<<endl;
int x = prex;
int y = prey; if(cx == 0 && cy == 0) x+=1;
if(cx == 0 && cy == 1) x-=1;
if(cx == 1 && cy == 0) y+=1;
if(cx == 1 && cy == 1) y-=1;
prex = x;
prey = y; if(x == nx && y == ny) return true; w>>=2;
} return false;
} void bfs(Snake s)
{
queue<Snake> Q;
Q.push(s);
vis[s.x][s.y][s.zt] = 1; while(!Q.empty()){
if(ans != -1){
break;
}
Snake now = Q.front();
Q.pop();
// cout<<"Now "<<now.x<<" "<<now.y<<" ZT"<<now.zt<<" t"<<now.t<<endl; for(int i = 0; i < 4; i++){
int x = now.x - dx[i];
int y = now.y - dy[i];
int zt = now.zt>>2; if(dx[i] == 1 && dy[i] == 0) zt += (0<<((k-2)*2));
if(dx[i] == -1 && dy[i] == 0) zt += (1<<((k-2)*2));
if(dx[i] == 0 && dy[i] == 1) zt += (2<<((k-2)*2));
if(dx[i] == 0 && dy[i] == -1) zt += (3<<((k-2)*2)); Snake tmp;
tmp.x = x,tmp.y = y,tmp.zt = zt,tmp.t = now.t+1; if(x<1 || x>n || y<1 || y>m || vis[x][y][zt] || stone[x][y]) continue;
if(check_fail(now,x,y)) continue; vis[x][y][zt] = 1; if(x == 1 && y == 1){
ans = tmp.t;
break;
}
Q.push(tmp);
}
}
} int main()
{
// freopen("in.txt","r",stdin);
int cnt = 0;
while(scanf("%d%d%d",&n,&m,&k)){
cnt++;
if(n == 0 && m == 0 && k == 0) break;
CLR(vis,0);
CLR(stone,0);
snake.zt = 0;
snake.t = 0;
ans = -1; scanf("%d%d",&snake.x,&snake.y);
int prex = snake.x;
int prey = snake.y;
for(int i = 1; i < k; i++){
int x,y;
scanf("%d%d",&x,&y);
int cx = x - prex;
int cy = y - prey;
prex = x;
prey = y; snake.zt<<=2;
if(cx == 1 && cy == 0) snake.zt += 0;
if(cx == -1 && cy == 0) snake.zt += 1;
if(cx == 0 && cy == 1) snake.zt += 2;
if(cx == 0 && cy == -1) snake.zt += 3;
} int l;
scanf("%d",&l);
for(int i = 1; i <= l; i++){
int x,y;
scanf("%d%d",&x,&y);
stone[x][y] = 1;
} bfs(snake);
if(snake.x == 1 && snake.y == 1) printf("Case %d: %d\n",cnt,0);
else printf("Case %d: %d\n",cnt,ans);
}
return 0;
}

POJ 1324 Holedox Moving (状压BFS)的更多相关文章

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

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

  2. poj 1324 Holedox Moving

    poj 1324 Holedox Moving 题目地址: http://poj.org/problem?id=1324 题意: 给出一个矩阵中,一条贪吃蛇,占据L长度的格子, 另外有些格子是石头, ...

  3. POJ 1324 Holedox Moving 搜索

    题目地址: http://poj.org/problem?id=1324 优先队列---A*的估价函数不能为蛇头到(1,1)的距离,这样会出错. 看了discuss,有大神说这题A*的估价函数为BFS ...

  4. 拯救大兵瑞恩 HDU - 4845(状压bfs || 分层最短路)

    1.状压bfs 这个状压体现在key上  我i们用把key状压一下  就能记录到一个点时 已经拥有的key的种类 ban[x1][y1][x2][y1]记录两个点之间的状态 是门 还是墙 还是啥都没有 ...

  5. P2622 关灯问题II(状压bfs)

    P2622 关灯问题II 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j] ...

  6. HDU 4012 Paint on a Wall(状压+bfs)

    Paint on a Wall Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) ...

  7. HDU Stealing Harry Potter's Precious(状压BFS)

    状压BFS 注意在用二维字符数组时,要把空格.换行处理好. #include<stdio.h> #include<algorithm> #include<string.h ...

  8. 状压BFS

    ​题意:1个机器人找几个垃圾,求出最短路径. 状压BFS,这道题不能用普通BFS二维vis标记数组去标记走过的路径,因为这题是可以往回走的,而且你也不能只记录垃圾的数量就可以了,因为它有可能重复走同一 ...

  9. POJ 3254 Corn Fields (状压dp)

    题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...

随机推荐

  1. 第28月第24天 requestSerializer

    1. requestSerializer关于 requestSerializer它就是AFNetworking参数编码的序列化器,它一共有三种编码格式: AFHTTPRequestSerializer ...

  2. COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问。最新解决方案

    检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问. (异常来自 HRE ...

  3. 第六章 接口,lamda表达式与内部类

    接口 接口可以包含常量, 且不需要publish static final修饰, 接口的域会自动添加该修饰符. Java建议不要写多余的代码,因此省略修饰符更简洁. 全部都是常量的接口背离了接口的初衷 ...

  4. “百度杯”CTF比赛 2017 二月场 爆破-3

    进入题目,题目源码: <?php error_reporting(0);session_start();require('./flag.php');if(!isset($_SESSION['nu ...

  5. 一文掌握 Linux 性能分析之 CPU 篇

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 平常工作会涉及 ...

  6. 022_word中如何正确的使用正则表达式进行搜索

    一.word中正则表达式详解 https://www3.ntu.edu.sg/home/ehchua/programming/howto/PowerUser_MSOffice.html 实战举例: ( ...

  7. ActiveMQ:使用Python访问ActiveMQ

    Windows 10家庭中文版,Python 3.6.4,stomp.py 4.1.21 ActiveMQ支持Python访问,提供了基于STOMP协议(端口为61613)的库. ActiveMQ的官 ...

  8. Java并发编程的4个同步辅助类

    Java并发编程的4个同步辅助类(CountDownLatch.CyclicBarrier.Semphore.Phaser) @https://www.cnblogs.com/lizhangyong/ ...

  9. PID控制器开发笔记之十三:单神经元PID控制器的实现

    神经网络是模拟人脑思维方式的数学模型.神经网络是智能控制的一个重要分支,人们针对控制过程提供了各种实现方式,在本节我们主要讨论一下采用单神经元实现PID控制器的方式. 1.单神经元的基本原理 单神经元 ...

  10. 【MySql】update用法

    update 语句可用来修改表中的数据, 简单来说基本的使用形式为: update 表名称 set 列名称=新值 where 更新条件; 以下是在表 students 中的实例: 将 id 为 5 的 ...