哈理工oj 2035 Diablo【BFS+DFS】

来源:互联网 发布:unity3d 离散事件仿真 编辑:程序博客网 时间:2024/06/01 08:55

DiabloTime Limit: 1000 MSMemory Limit: 65536 KTotal Submit: 47(23 users)Total Accepted: 25(22 users)Rating: Special Judge: NoDescription

Diablo是地狱中的三大魔王之一,有着非常强大的破坏力,Diablo期望着可以将一切都投入到地狱之中。为了不让Diablo的计划得逞,一位英雄决定挺身而出,试图击败Diablo。DIablo喜欢把眼前的区域变成一片火海,Diablo吐出火焰的蔓延是有一定规律的,火焰总是会向能量较低的区域蔓延。英雄如果不想被Diablo击败的话,就需要在Diablo喷出火焰的一瞬间逃到火焰烧不到的地方,但是他只能在这一瞬逃出3个单位长度的距离。现在我们给出现场的一个地图,并且给出Diablo和英雄所在的位置,我们要知道英雄是否可以逃脱Diablo的攻击。(火焰蔓延方向只能是上、下、左、右)

Input本题有多组测试数据,对于每组数据第一行输入6个非负整数,分别表示地图的长、宽(分别对应m、n),Diablo的坐标以及英雄的坐标。接下来n行每行输入m个数,表示地图上每个点的能量值(值在32位有符号整数范围内)。m、n值均不大于100,且我们保证数据合理合法。Output如果英雄可以逃脱Diablo的攻击,输出Hero will be back并换行,否则输出Diablo win并换行。Sample Input

3 3 0 0 2 2
5 4 1
4 3 2
3 2 1


6 4 0 0 2 3
5 2 6 7 3 0
4 3 8 1 5 5
9 1 8 3 6 5
8 7 6 5 4 2

Sample Output

Diablo win

Hero will be back


Hint我们来看看第二组样例数据,Diablo所处的位置是(0, 0),那么Diablo在地图上左上角的点,其能量值为5。英雄所在的位置是(2, 3),也就是我们看到地图上第三行第四列的位置,其能量值为3。不过火焰只能从能量高的地方向能量低的地方蔓延,尽管英雄处在的位置能量值较低,但是火焰却无法蔓延到这里,因为有能量相对较高的地势阻隔。假设英雄所在的位置能被火焰蔓延到,他只需在3步内找到一个火焰不可达的合法区域即可躲过攻击。Source2014 Winter Holiday Contest 5Author杨和禹

思路:BFS广搜预处理,把火焰能够烧到的地方都用vis【】【】数组标记上为1.然后用DFS主人公的位子,控制3步去走,如果能够走的到vis【】【】==0的地方,就表示主人公可以back,否则就会被干掉。

BFS:

void bfs(int x,int y){    memset(vis,0,sizeof(vis));    now.x=x;    now.y=y;    queue<zuobiao >s;    s.push(now);    vis[x][y]=1;    while(!s.empty())    {        now=s.front();        s.pop();        for(int i=0;i<4;i++)        {            nex.x=now.x+fx[i];            nex.y=now.y+fy[i];            if(nex.x>=0&&nex.x<m&&nex.y>=0&&nex.y<n&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]<=a[now.x][now.y])//在符合边界的情况下,并且要符合只能向能量值小的地方蔓延火焰            {                vis[nex.x][nex.y]=1;//标记上这个点会被火焰烧到。                s.push(nex);            }        }    }}
DFS部分:

void dfs(int x,int y,int step)//坐标,和当前一共走了多少步{    if(step>3)//如果大于三步直接return    {        return ;    }    if(vis[x][y]==0)//如果走到了火焰蔓延不到的地方    {        ok=1;//标记上可以回家了        return ;    }    else    {        for(int i=0;i<4;i++)        {            int xx=x+fx[i];            int yy=y+fy[i];            if(xx>=0&&xx<m&&yy>=0&&yy<n&&vis2[xx][yy]==0)//走法合法。            {                vis2[xx][yy]=1;                dfs(xx,yy,step+1);                vis2[xx][yy]=0;            }        }    }}
完整AC代码:
#include<stdio.h>#include<string.h>#include<queue>using namespace std;struct zuobiao{    int x,y;}now,nex;int a[200][200];int vis[200][200];int vis2[200][200];int fx[4]={0,0,1,-1};int fy[4]={1,-1,0,0};int n,m,sx,sy,hx,hy,ok;void bfs(int x,int y){    memset(vis,0,sizeof(vis));    now.x=x;    now.y=y;    queue<zuobiao >s;    s.push(now);    vis[x][y]=1;    while(!s.empty())    {        now=s.front();        s.pop();        for(int i=0;i<4;i++)        {            nex.x=now.x+fx[i];            nex.y=now.y+fy[i];            if(nex.x>=0&&nex.x<m&&nex.y>=0&&nex.y<n&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]<=a[now.x][now.y])            {                vis[nex.x][nex.y]=1;                s.push(nex);            }        }    }}void dfs(int x,int y,int step){    if(step>3)    {        return ;    }    if(vis[x][y]==0)    {        ok=1;        return ;    }    else    {        for(int i=0;i<4;i++)        {            int xx=x+fx[i];            int yy=y+fy[i];            if(xx>=0&&xx<m&&yy>=0&&yy<n&&vis2[xx][yy]==0)            {                vis2[xx][yy]=1;                dfs(xx,yy,step+1);                vis2[xx][yy]=0;            }        }    }}int main(){    while(~scanf("%d%d%d%d%d%d",&n,&m,&sx,&sy,&hx,&hy))    {        for(int i=0;i<m;i++)        {            for(int j=0;j<n;j++)            {                scanf("%d",&a[i][j]);            }        }        ok=0;        bfs(sx,sy);        memset(vis2,0,sizeof(vis2));        dfs(hx,hy,0);        if(ok==1)        {            printf("Hero will be back\n");        }        else        {            printf("Diablo win\n");        }    }}





0 0
原创粉丝点击