ZOJ 3652Maze

Maze

Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 44   Accepted Submission(s) : 13
Problem Description
Celica is a brave person and believer of a God in the bright side. He always fights against the monsters that endanger humans. One day, he is asked to go through a maze to do a important task.

The maze is a rectangle of n*m, and Celica is at (x1, y1) at the beginning while he needs to go to (x2, y2). And Celica has a Mobility of l. When he moves a step the movility will decreased by 1. If his mobility equals to 0, he can't move anymore in this turn. And no matter how much mobility Celica uses in one turn, his movility will become l again in the next turn. And a step means move from one lattice to another lattice that has an adjacent edge.

However, due to the world's rule and the power of magic, there is something called Dominance in the maze. Some lattices may be dominated by some monsters and if Celica goes into these lattices, his mobility will be reduced to 0 at once by the monster's magic power. And monsters have strong "Domain awareness" so one lattice won't be dominated by more than one monster.

But luckily, Celica gets a strong power from his God so that he can kill this monsters easily. If Celica goes into a lattice which a monster stands on, he can kill the monster without anytime. If a monsters is killed, the lattices it dominates will no longer be dominated by anyone(or we can say they are dominated by Celica) and these lattices will obey the rule of mobility that normal lattices obey.

As for the task is so important that Celica wants to uses the least turn to go to (x2, y2). Please find out the answer.


PS1: It doesn't matter if Celica doesn't kill all the monsters in the maze because he can do it after the task and a monster may appear at a lattice that is not dominated by it, even a lattice that is not dominated by any monsters.

PS2: We define (1,1) as the top left corner. And monsters won't move.

PS3: No matter which lattice Celia gets in, the change of mobility happens first.

PS4: We promise that there is no two monsters have same position and no monster will appear at the start point of Celica.

Input


The first contains three integers, n, m, l.(1≤n, m≤50, 1≤l≤10)

Then there follows n lines and each line contains m integers. The j-th integer p in the line i describe the lattice in the i line and j row. If p euqals to -1, it means you can't get into it. If p euqals to 0, it means the lattice is not dominated by any monster. If p is larger than 0, it means it is dominated by the p-th monster.

And then in the n+2 line, there is an integer k(0≤k≤5) which means the number of monster.

Then there follows k lines. The i-th line has two integers mean the position of the i-th monster.

At last, in the n+k+3 lines, there is four integers x1, y1, x2, y2.

Output

If Celica can't get to the (x2, y2), output "We need God's help!", or output the least turn Celica needs.

Sample Input

5 5 4
2 2 2 1 0
-1 2 2 -1 1
2 2 2 1 1
1 1 1 1 0
1 2 2 -1 0
2
4 2
1 1
5 1 1 5
5 5 4
1 1 1 1 1
1 2 2 -1 -1
2 2 -1 2 2
-1 -1 2 2 2
2 2 2 2 2
2
2 2
1 2
1 1 5 5

Sample Output

4
We need God's help!

Hit

In the first case, Celica goes to (4,1) in turn 1. Then he goes to (4,2) in turn 2. After he gets (4,2), kill the monster 1. He goes through (4,3)->(4,4)>(3,4)->(3,5) in turn 3. At last he goes (2,5)->(1,5) in turn 4.


状态压缩广搜

有一个地图,地图划分为几个怪兽拥有的地盘,在杀死对应怪兽之前,在怪兽拥有的地盘上每回合只能移动一部,然后就进入下一回合。

每回合猪脚有l的行动力。求猪脚至少需要几回合能达到目的地


因为怪物最多只有5个  所以可以使用状态压缩来保存队列中每个点杀死怪兽的情况

四维数组标记判重即可


有几个坑点  

1、起点终点相同  1回合

2、到达终点时行动力为零也不需要等下一回合

3、怪兽不一定在自己的地盘上


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<string>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#define inf 1<<30
#define LL long long
#define maxn 1<<24
using namespace std;
int Map[55][55];//地图
int Mp[55][55];//怪兽所在点。。。有点懒了  
bool vis[55][55][1<<6][11];//标记
int dir[4][2]= {0,1,0,-1,1,0,-1,0};
int n,m,l;
int k;
struct node
{
    int x,y;
    int t;//移动力
    int T;//回合数
    int vis;//状态压缩
    friend bool operator < (node a,node b)
    {
        return a.T>b.T;
    }
    bool cheak()
    {
        if(x>0&&x<=n&&y>0&&y<=m)
            return true ;
        return false ;
    }
} st,e,ed;

void bfs()
{
    st.t=l;
    st.T=1;
    st.vis=0;
    priority_queue<node>q;
    q.push(st);
    vis[st.x][st.y][st.vis][st.t]=true ;
    while(q.size())
    {
        st=q.top();
        q.pop();
        //cout<<st.x<<" "<<st.y<<" "<<st.T<<" "<<st.t<<endl;
        if(st.x==ed.x&&st.y==ed.y)
        {
            printf("%d\n",st.T);
            return ;
        }
        if(st.t==0)
        {
            st.t=l;
            st.T++;
            if(!vis[st.x][st.y][st.vis][st.t])
                q.push(st);
            vis[st.x][st.y][st.vis][st.t]=true ;
            continue ;
        }
        for(int i=0; i<4; i++)
        {
            e=st;
            e.x+=dir[i][0];
            e.y+=dir[i][1];
            if(e.cheak())
            {
                if(Map[e.x][e.y]!=-1)
                {
                    if(Map[e.x][e.y]==0)
                    {
                        if(Mp[e.x][e.y])
                        {
                            if(!(e.vis&(1<<Mp[e.x][e.y])))
                                e.vis+=1<<Mp[e.x][e.y];
                        }

                        e.t--;
                        if(!vis[e.x][e.y][e.vis][e.t])
                        {
                            vis[e.x][e.y][e.vis][e.t]=true ;
                            q.push(e);
                        }
                    }
                    else
                    {
                        if(e.vis&(1<<Map[e.x][e.y]))
                        {
                            if(Mp[e.x][e.y])
                            {
                                if(!(e.vis&(1<<Mp[e.x][e.y])))
                                {
                                    e.vis+=(1<<Mp[e.x][e.y]);
                                }
                            }
                            e.t--;
                            if(!vis[e.x][e.y][e.vis][e.t])
                            {
                                vis[e.x][e.y][e.vis][e.t]=true ;
                                q.push(e);
                            }
                        }
                        else
                        {
                            if(Mp[e.x][e.y])
                            {
                                if(!(e.vis&(1<<Mp[e.x][e.y])))
                                {
                                    e.vis+=(1<<Mp[e.x][e.y]);
                                }
                            }
                            e.t=0;
                            if(!vis[e.x][e.y][e.vis][e.t])
                            {
                                vis[e.x][e.y][e.vis][e.t]=true ;
                                q.push(e);
                            }
                        }
                    }
                }
            }
        }
    }
    printf("We need God's help!\n");
    return ;
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&l))
    {
        memset(vis,false ,sizeof(vis));
        memset(Mp,0 ,sizeof(Mp));
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
                scanf("%d",&Map[i][j]);
        }
        scanf("%d",&k);
        for(int i=1; i<=k; i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            Mp[x][y]=i;
        }
        scanf("%d%d%d%d",&st.x,&st.y,&ed.x,&ed.y);
        if(st.x==ed.x&&st.y==ed.y)
        {
            printf("0\n");
            continue ;
        }
        bfs();
    }
    return 0;
}



你可能感兴趣的:(ZOJ 3652Maze)