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;
}

最新文章

  1. sql server中除数为零的处理技巧
  2. 【poj1041】 John&#39;s trip
  3. Setup network on centos 7
  4. Windows下MemCache多端口安装配置
  5. linux power button
  6. CSS笔记(一)CSS规则
  7. 【leetcode】13. Roman to Integer
  8. 【转】Spring的WebServiceTemplate访问WebService的方法及其本质原理
  9. 浙工大C语言入门指南 (仅供参考)
  10. CentOS-6.3安装配置SVN
  11. “字符串替换” 和 “模板设置” (application/config.php)
  12. web移动端区分Android或者ios系统
  13. LeetCode 389 Find the Difference 解题报告
  14. Android studio新建文件出现setContentView(R.layout.activity_main);中的R标红错误解决方法
  15. 为什么 APM 能提升 IT 团队工作质量?
  16. L306 词汇题
  17. Vmware 不使用物理内存运行缓慢的处理方法
  18. 因默认包扫描问题导致的SpringBoot项目无法启动问题
  19. netbeans工具使用xdebug断点调试php源码
  20. POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】

热门文章

  1. VS Code中编写C
  2. Linux中安装C++编译器codeBlock,并配置opencv链接库
  3. openwrt 加入nand flash的支持
  4. 关于redis服务无法启动问题
  5. Docker: repository, image, container
  6. Visual Studio Code 的使用方法和技巧
  7. Django目录
  8. linux服务安装与配置(二):安装xinetd服务
  9. vue 使用swiper的一些问题(页面渲染问题)
  10. Eclipse安装git插件以及关联导入GitHub项目