POJ 1324 Holedox Moving (状压BFS)
POJ 1324 Holedox Moving (状压BFS)
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 18091 Accepted: 4267Description
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)的更多相关文章
- POJ - 1324 Holedox Moving (状态压缩+BFS/A*)
题目链接 有一个n*m(1<=n,m<=20)的网格图,图中有k堵墙和有一条长度为L(L<=8)的蛇,蛇在移动的过程中不能碰到自己的身体.求蛇移动到点(1,1)所需的最小步数. 显然 ...
- poj 1324 Holedox Moving
poj 1324 Holedox Moving 题目地址: http://poj.org/problem?id=1324 题意: 给出一个矩阵中,一条贪吃蛇,占据L长度的格子, 另外有些格子是石头, ...
- POJ 1324 Holedox Moving 搜索
题目地址: http://poj.org/problem?id=1324 优先队列---A*的估价函数不能为蛇头到(1,1)的距离,这样会出错. 看了discuss,有大神说这题A*的估价函数为BFS ...
- 拯救大兵瑞恩 HDU - 4845(状压bfs || 分层最短路)
1.状压bfs 这个状压体现在key上 我i们用把key状压一下 就能记录到一个点时 已经拥有的key的种类 ban[x1][y1][x2][y1]记录两个点之间的状态 是门 还是墙 还是啥都没有 ...
- P2622 关灯问题II(状压bfs)
P2622 关灯问题II 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j] ...
- 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) ...
- HDU Stealing Harry Potter's Precious(状压BFS)
状压BFS 注意在用二维字符数组时,要把空格.换行处理好. #include<stdio.h> #include<algorithm> #include<string.h ...
- 状压BFS
题意:1个机器人找几个垃圾,求出最短路径. 状压BFS,这道题不能用普通BFS二维vis标记数组去标记走过的路径,因为这题是可以往回走的,而且你也不能只记录垃圾的数量就可以了,因为它有可能重复走同一 ...
- POJ 3254 Corn Fields (状压dp)
题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...
随机推荐
- Entity Framework查询
Entity Framework是个好东西,虽然没有Hibernate功能强大,但使用更简便.今天整理一下常见SQL如何用EF来表达,Func形式和Linq形式都会列出来(本人更喜欢Func形式). ...
- Stm32复习之时钟系统
地点:南图 这部分的内容是整个STM32学习知识的核心,不管是什么微控制器处理器,时钟系统都是其核心类似于人之心脏,因此学好理解这一章节至关重要. 为了便于理解这一系统,将从以下几个层次来讲.(忘了是 ...
- dubbo负载均衡与集群集群容错
1.负载均衡 在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用. 1. 负载均衡策略 Random LoadBalance 随机,按权重设置随机概率.(默认值)在一个 ...
- 可持久化并(xian)查(duan)集(shu)
随便地点开了这道可持久化并查集,发现了真相...这和并查集有 PI 关系哦.除了find_father(而且还不能路径压缩),全都是线段树0.0 题目链接: luogu.org 题目没什么描述,就是三 ...
- Alpha 事后诸葛亮(团队)
前言 事后诸葛亮?作业名真的不好听,下一届还要沿用吗? 队名:小白吃 通向hjj博客的任意门 思考总结 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? ...
- .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
原因是缺少了启动文件,startup_xxx.s,只需要把该文件添加到项目下即可,该文件如果找不到则重新建立工程,每个新的工程建立后系统都会询问是否添加启动文件,选择添加启动文件即可. 注意选择对应容 ...
- Python爬虫实战一之爬取QQ音乐
一.前言 前段时间尝试爬取了网易云音乐的歌曲,这次打算爬取QQ音乐的歌曲信息.网易云音乐歌曲列表是通过iframe展示的,可以借助Selenium获取到iframe的页面元素, 而QQ音乐采用的是 ...
- MS SQL Server 时间函数
日期和时间数据类型 数据类型 存储(字节) 日期范围 精确度 格式示例 DateTime 8 1753年1月1日 - 9999年12月31日 3 1/3毫秒 yyyy-MM-dd hh:mm:ss.n ...
- 【原创】大叔经验分享(19)spark on yarn提交任务之后执行进度总是10%
spark 2.1.1 系统中希望监控spark on yarn任务的执行进度,但是监控过程发现提交任务之后执行进度总是10%,直到执行成功或者失败,进度会突然变为100%,很神奇, 下面看spark ...
- js定义数组集合
简单描述:最近脑子有点抽,js要用到数组,竟然傻傻的写了 var [] str = .简直是糟糕的不要不要的 //js代码var str = [];var str =new Array(); 啥也不说 ...
