POJ-1324-Holedox Moving(BFS)

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

Beijing 2002

思路:从头部開始想尾部走,不同方向代表不同的值,就得到蛇的状态,然后就是普通的BFS,还要注意不能咬到自己,首尾相连也不行。

#include <stdio.h>

struct S{
int step,x[9],y[9],head;
}que[1000000];

bool vis[20][20][16384];
int mp[20][20],nxt[4][2]={{1,0},{0,-1},{0,1},{-1,0}},mi[8]={1,4,16,64,156,1024,4096,16384};

int main()
{
    int n,m,l,i,j,k,x,y,head,temp,lx,ly,tl,valx,valy,casenum=1,top,bottom;

    while(~scanf("%d%d%d",&n,&m,&l) && n)
    {
        for(i=0;i<l;i++)
        {
            scanf("%d%d",&x,&y);

            que[0].x[i]=x-1;
            que[0].y[i]=y-1;
        }

        for(i=0;i<n;i++) for(j=0;j<m;j++) mp[i][j]=1;
        for(i=0;i<n;i++) for(j=0;j<m;j++) for(k=0;k<mi[l-1];k++) vis[i][j][k]=0;

        scanf("%d",&k);

        while(k--)
        {
            scanf("%d%d",&x,&y);

            mp[x-1][y-1]=0;
        }

        que[0].step=0;
        que[0].head=0;

        top=0;
        bottom=1;

        while(top<bottom)
        {
            if(!que[top].x[que[top].head] && !que[top].y[que[top].head])
            {
                printf("Case %d: %d\n",casenum++,que[top].step);

                break;
            }

            head=que[top].head-1;

            if(head==-1) head=l;

            que[top].step++;

            for(i=0;i<4;i++)
            {
                x=que[top].x[head]=que[top].x[que[top].head]+nxt[i][0];
                y=que[top].y[head]=que[top].y[que[top].head]+nxt[i][1];

                if(x>=0 && x<n && y>=0 && y<m && mp[x][y])
                {
                    temp=0;

                    lx=x;
                    ly=y;

                    tl=0;

                    for(j=que[top].head;tl<l;j++)
                    {
                        if(j==l+1) j=0;

                        if(que[top].x[j]==x && que[top].y[j]==y) break;//假设会咬到自己

                        if(tl<l-1)//计算状态
                        {
                            valx=lx-que[top].x[j];
                            valy=ly-que[top].y[j];

                            if(valx==0 && valy==1) temp=temp<<2;
                            else if(valx==1 && valy==0) temp=temp<<2|1;
                            else if(valx==-1 && valy==0) temp=temp<<2|2;
                            else if(valx==0 && valy==-1) temp=temp<<2|3;

                            lx=que[top].x[j];
                            ly=que[top].y[j];
                        }

                        tl++;
                    }

                    if(tl==l && !vis[x][y][temp])//假设不会咬到自己而且该状态没有訪问过
                    {
                        vis[x][y][temp]=1;

                        que[top].head--;

                        if(que[top].head==-1) que[top].head=l;

                        que[top].x[head]=x;
                        que[top].y[head]=y;

                        que[bottom++]=que[top];

                        que[top].head++;

                        if(que[top].head==l+1) que[top].head=0;
                    }
                }
            }

            top++;
        }

        if(top==bottom) printf("Case %d: -1\n",casenum++);
    }
}
时间: 2024-10-23 17:47:07

POJ-1324-Holedox Moving(BFS)的相关文章

poj 1324 Holedox Moving

poj 1324 Holedox Moving 题目地址: http://poj.org/problem?id=1324 题意: 给出一个矩阵中,一条贪吃蛇,占据L长度的格子, 另外有些格子是石头, 不能通过, 请问蛇到达 (1,1)格子最短距离. 明显的BFS问题, 将每一个可以走的格子进入队列, 格子判断能否走?(给蛇身体标序号(蛇头l, 蛇尾1,其他置为0), 当 fabs(cur_num - tmp_num)>=l 的时候,说明蛇的身体已经离开之前的格子了. #include <ios

poj 1324 Holedox Moving A*算法对bfs的优化

题意: 迷宫里有一条贪食蛇,求它的蛇头到迷宫左上角最少要多少步. 分析: 关键是将蛇的状态压缩编码,然后bfs,超时就改A*,这题有类似最短路径的性质,A*发现节点重复后不需要更新直接舍弃即可. 代码: //poj 1324 //sep9 #include <iostream> #include <algorithm> #include <queue> using namespace std; struct state { int x[10],y[10]; }; str

POJ 1324 [Holedox Moving] 状态压缩BFS

题目链接:http://poj.org/problem?id=1324 题目大意:n*m网格里有蛇和障碍,蛇只能向空格处移动,不能撞到自己,问到(1,1)的最短步数,如无法到达输出-1. 关键思想:不能直接对蛇头进行BFS,因为蛇身对蛇头的决策也有影响,故BFS时应该保存蛇身状态,我们放在state里用位运算来做.因为根据蛇头和每一节延伸的方向(东南西北)我们可以还原出整条蛇.比较坑的是这道题用pow会超时,自己写一个好啦. 由于vis数组很大,如果对于每个Case都初始化vis数组浪费时间,所

POJ 1324 Holedox Moving 贪吃蛇 状态压缩 BFS

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.

poj 1324 状态压缩+bfs

http://poj.org/problem?id=1324 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

poj1324 Holedox Moving

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 l

Dearboy&#39;s Puzzle (poj 2308 搜索 dfs+bfs)

Language: Default Dearboy's Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1202   Accepted: 208 Description Dearboy is a game lover. Recently, he loves playing the game Lian Lian Kan. This game is played on a board with N*M grids

poj 3026 Borg Maze (bfs + 最小生成树)

链接:poj 3026 题意:y行x列的迷宫中,#代表阻隔墙(不可走),空格代表空位(可走),S代表搜索起点(可走) A代表外星人站(可走),现在要从S出发,将S和所有的A之间都连通,求路线总距离最小值 分析:可以先用bfs将所有的A,S两两之间的最短距离,题目的目的是将S与所有的A连通,使得总距离最小, 所有任选一点开始按最小生成树的算法做就行,并非非要从S点开始 注:题目输入x,y后可能有很多空格,可以用gets将多余的空格取走,开数组是尽量开大点,之前虽然开的比题目数据     稍大,但一

POJ 2329 (暴力+搜索bfs)

Nearest number - 2 Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3943 Accepted: 1210 Description Input is the matrix A of N by N non-negative integers. A distance between two elements Aij and Apq is defined as |i ? p| + |j ? q|. Your pro

poj 1077 八数码(BFS+康托展开)

1 /* 2 题意:八数码问题,给出3*3的矩阵含1~8以及x,给出一个符合的解使得移动后的矩阵的顺序为1~8,最后为x 3 4 题解:BFS 5 需要用到康托展开来表示状态,不然数组无法完全表示所有状态,这样BFS就无法判断找不到解的情况(status 6 的0ms,0KB究竟是怎么做到的,简直不能想象=.=) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 #include <queue> 11 #include &