Holedox Moving
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 16980   Accepted: 4039

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

题意:在一个n*m的方格上,有一条长为L的蛇,由L个关节组成,每次蛇头不能碰到身体和石头,求最少多少步到达(1,1)这个位置.
这道题我不大会,参考了一下其他神犇的博客.
分析:如果没有身体这个限制,那么就是一道bfs的题,如果有身体这个限制,我们就要想办法记录下它的每个关节在哪个位置,下一次会往哪里走.
       显然,我们可以用一个结构体记录每个关节的位置,每个关节下一次走的位置就是它的上一个关节原来的位置,这样的话还是有一个问题:bfs需要一个vis数组记录曾经搜索过的状态,在这道题中我们该记录什么呢?头的位置肯定是要记录的,但是每个关节的位置记录不下来,空间会爆掉,那我们可以记录每个关节行走的方向,但是这样处理比较麻烦,于是我们记录每个关节关于它的后一个关节的相对运动方向.但是这样的话似乎要开一个很多维的数组,这样也实在是太麻烦了,于是可以很自然的想到状态压缩,可是我们有4个方向,压成二进制每位表示的不够啊,那么我们就每2位表示一节的方向就好了.
       有一个优化:由于vis数组很大,我们如果每次清空都会花费大量的时间,所以我们不再是赋值为0,1,而是看它是不是等于当前的tot(第tot组数据),这样就相当于是一个bool判断.
       不过这样还是会超时啊(要疯了!),那么就要用到搜索中常用的技巧了--启发式搜索,也就是A*,不过太麻烦了,就没写,以下是裸bfs代码:
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; int n, m, l,tot = ,a[][];
int vis[][][ << ],k;
int d[][] = {
-,,-,
,-,,
-,,-
}; int dx[] = { ,-,, }, dy[] = { ,,,- }; struct node
{
int x[], y[], cnt;
}; bool check(int x, int y, node u)
{
for (int i = ; i <= l; i++)
if (x == u.x[i] && y == u.y[i])
return false;
return true;
} int bfs(node x)
{
queue<node> q;
q.push(x);
while (!q.empty())
{
node u = q.front();
q.pop();
if (u.x[] == && u.y[] == )
return u.cnt;
for (int i = ; i < ; i++)
{
node v;
int tx = u.x[] + dx[i], ty = u.y[] + dy[i];
if (tx < || tx > n || ty < || ty > m || a[tx][ty])
continue;
if (!check(tx, ty, u))
continue;
u.x[] = tx, u.y[] = ty;
int zhuangtai = ;
for (int j = l; j >= ; j--)
{
v.x[j] = u.x[j - ];
v.y[j] = u.y[j - ];
if (j != l)
{
int temp = d[v.x[j] - v.x[j + ] + ][v.y[j] - v.y[j + ] + ];
zhuangtai |= (temp << ( - j * ));
}
}
if (vis[tx][ty][zhuangtai] == tot)
continue;
vis[tx][ty][zhuangtai] = tot;
v.cnt = u.cnt + ;
q.push(v);
}
}
return -;
} int main()
{
while (scanf("%d%d%d", &n, &m, &l) == )
{
memset(a, , sizeof(a));
int temp = ,tx,ty;
node init;
scanf("%d%d", &init.x[], &init.y[]);
for (int i = ; i <= l; i++)
{
scanf("%d%d", &init.x[i], &init.y[i]);
tx = init.x[i - ] - init.x[i] + ;
ty = init.y[i - ] - init.y[i] + ;
temp |= (d[tx][ty] << ( - (i - ) * ));
}
vis[init.x[]][init.y[]][temp] = tot;
scanf("%d", &k);
for (int i = ; i <= k; i++)
{
int aa, bb;
scanf("%d%d", &aa, &bb);
a[aa][bb] = ;
}
init.cnt = ;
printf("Case %d: %d\n", tot++, bfs(init));
} return ;
}

poj1324 Holedox Moving的更多相关文章

  1. poj 1324 Holedox Moving

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

  2. POJ 1324 Holedox Moving (状压BFS)

    POJ 1324 Holedox Moving (状压BFS) Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 18091 Acc ...

  3. POJ 1324 Holedox Moving 搜索

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

  4. UVALive 2520 Holedox Moving(BFS+状态压缩)

    这个题目在比赛的时候我们是没有做出来的,但是听到他们说进制哈希的时候,感觉真的是挺高端的,于是赛后开始补题,本着我的习惯在看题解之前自己再试着写一遍,我当时存储状态的方法是string + map,我 ...

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

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

  6. ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))

    求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其 ...

  7. HOJ题目分类

    各种杂题,水题,模拟,包括简单数论. 1001 A+B 1002 A+B+C 1009 Fat Cat 1010 The Angle 1011 Unix ls 1012 Decoding Task 1 ...

  8. BFS广搜题目(转载)

    BFS广搜题目有时间一个个做下来 2009-12-29 15:09 1574人阅读 评论(1) 收藏 举报 图形graphc优化存储游戏 有时间要去做做这些题目,所以从他人空间copy过来了,谢谢那位 ...

  9. poj 1324 状态压缩+bfs

    http://poj.org/problem?id=1324 Holedox Moving Time Limit: 5000MS   Memory Limit: 65536K Total Submis ...

随机推荐

  1. Ubuntu 16.04 换国内源

    官方渠道,图形界面,操作简单,可以说对新手及其友好!! 依次打开:搜索,软件与更新,第一个和第三个勾上,下载自,其它,然后在中国条目下选择你想使用的镜像站点,然后点“选择服务器”,然乎点击“关闭”,选 ...

  2. DD命令做备份和恢复

    正确的备份方法是先挂载移动硬盘分区:mount /dev/sdb5 /mnt 然后再备份:dd if=/dev/sda of=/mnt/backup_sda.img 恢复时同样要先挂载,再恢复:mou ...

  3. js函数式编程(二)-柯里化

    这节开始讲的例子都使用简单的TS来写,尽量做到和es6差别不大,正文如下 我们在编程中必然需要用到一些变量存储数据,供今后其他地方调用.而函数式编程有一个要领就是最好不要依赖外部变量(当然允许通过参数 ...

  4. 【线段树分治 01背包】loj#6515. 「雅礼集训 2018 Day10」贪玩蓝月

    考试时候怎么就是没想到线段树分治呢? 题目描述 <贪玩蓝月>是目前最火爆的网页游戏.在游戏中每个角色都有若干装备,每件装备有一个特征值 $w$ 和一个战斗力 $v$ .在每种特定的情况下, ...

  5. 【线段树 泰勒展开】Codechef April Challenge 2018 Chef at the Food Fair

    第一次写泰勒展开:本地和CC差距好大 题目大意 大厨住的城市里办了一场美食节.一条街上开设了$N$个摊位,编号为$1∼N$.这天开始时,第$i$个摊位的食物会导致食物中毒的概率是$P_i$.在这一天中 ...

  6. 【差分约束】poj1275Cashier Employment

    比较经典的差分约束 Description A supermarket in Tehran is open 24 hours a day every day and needs a number of ...

  7. vue-cli webpack配置cdn路径 以及 上线之后的字体文件跨域处理

    昨天搞了一下vue项目打包之后静态资源走阿里云cdn. 配置了半天,终于找到了设置的地方 config/index.js 里面设置build 下的 assetsPublicPath 打包的时候便可以添 ...

  8. 第3-5课 填充左侧菜单/品牌的添加 Thinkphp5商城第四季

    目录 左侧菜单的填充 品牌的添加 form标签里要加上method="post" enctype="multipart/form-data" form标签里如果 ...

  9. Django ORM (三) 查询,删除,更新操作

    ORM 查询操作 修改 views.py 文件 from django.shortcuts import render, HttpResponse from app01 import models f ...

  10. python之自定义排序函数sorted()

    sorted()也是一个高阶函数,它可以接收一个比较函数来实现自定义排序,比较函数的定义是,传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面, ...