xdoj1269(2017新生赛现场赛G题)

1269: The Binding Of Issac

时间限制: 1 Sec   内存限制: 128 MB
提交: 39   解决: 12
[ 提交][ 状态][ 讨论版]

题目描述

williamchen 每天就知道玩游戏,他最喜欢玩 The Binding Of Issac。

有时候他会进入一个充满石头的房间,有时候他需要控制以撒从这个房间的某个位置走到另一个位置。

为了简化问题,一个房间被抽象成一个二维矩阵(10*10),由下列符号组成。

S : 代表以撒现在所处的位置,地图中只会出现一个。

r : 代表地图中的石头,不能通过。

* : 代表地图中的空地,可以通过。

E : 代表以撒想要去的目标位置,地图上只能出现一个。

B : 代表炸弹,地图中只会出现一个。

以撒不能通过石头,也不能站在石头上,他每一秒中只能向上下左右四个方向之一移动一个距离。

炸弹的作用是,可以将上下左右的四块石头(如果有)全部清除,炸弹只能被放置在空地上。以撒现在没有炸弹,他可能需要去捡一个炸弹帮助他到达目的地或是让他更快地到达目的地。捡这个炸弹或者放置炸弹都是不用耗费时间的。

以撒只能在自己的脚下放置炸弹,因为他已经捡到防爆道具,所以不需要担心是否炸伤自己。请问以撒最快用几秒能到达目的地,如果不能到达,请输出-1。

输入

包含一个 10 * 10 的二维矩阵。

输出

输出一个数,代表到达目的地的最短时间,或是-1 代表不能到达目的地。

样例输入

**********
**********
**********
**********
**********
**********
**********
**********
rrrrrr****
****ErS**B

样例输出

 
8

思路:一道较为复杂的迷宫问题,用bfs求解,但状态不只是点的坐标,还有当前手中炸弹的数目。

见代码:

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
int sx,sy,ex,ey,zx,zy;
int ans=1000000000;
char map[20][20];
int gg[20][20]; //用来判定这个格是否可以走
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
struct node
{
    int x,y,t,bomb; //分别为x坐标,y坐标,当前时间,和手中炸弹数
};
    queue<node> q;
bool judge(int x,int y)
{
    if(0<= x && x <10 && 0 <= y && y<10) return 1;
    return 0;
}
void bfs()
{
    int i,j,x1,y1;
    node n1 ;
    n1.x = sx;
    n1.y = sy;
    n1.t = 0;
    n1.bomb=0;
    q.push(n1);
    while( !q.empty() )
    {

        node tmp = q.front();
        q.pop();
        if(tmp.x==ex&&tmp.y==ey)
        {
        	ans=tmp.t;
			break;
		}
        for(i=0; i<4; i++)
        {

            x1 = tmp.x + dx[i];
            y1 = tmp.y + dy[i];
            if( gg[x1][y1]<tmp.bomb&& judge(x1,y1) )
            {
                if(map[x1][y1]=='r'&&tmp.bomb>0)
				{
				node n2;
                n2.x = x1;
                n2.y = y1;
                n2.t = tmp.t +1;
                n2.bomb=tmp.bomb-1;
                gg[x1][y1]=tmp.bomb-1;
                q.push(n2);
				}
				else if(map[x1][y1]=='S'||map[x1][y1]=='E'||map[x1][y1]=='*')
				{
				node n2;
                n2.x = x1;
                n2.y = y1;
                n2.t = tmp.t +1;
                n2.bomb=tmp.bomb;
                gg[x1][y1]=tmp.bomb;
                q.push(n2);
				}
                else if(map[x1][y1]=='B')
                {
                node n2;
                n2.x = x1;
                n2.y = y1;
                n2.t = tmp.t +1;
                n2.bomb=tmp.bomb+1;
                gg[x1][y1]=tmp.bomb+1;
                q.push(n2);
				}
            }
        }
    }
}
int main()
{
    int i,j;
    for(i=0; i<10; i++)
    {
         gets(map[i]);
    }

    for(i=0; i<10; i++)
    {
         for(j=0;j<10;j++)
         {
         	 gg[i][j]=-1;  //因为初始炸弹为零时也可以走
		 }
    }
        for(i=0; i<10; i++)
    {
         for(j=0;j<10;j++)
         {
         	if(map[i][j]=='S')
         	{
         		sx=i;
         		sy=j;
			 }
			 if(map[i][j]=='E')
         	{
         		ex=i;
         		ey=j;
			 }
			 if(map[i][j]=='B')
         	{
         		zx=i;
         		zy=j;
			 }
		 }
    }
    bfs();
    if(ans==1000000000)
    printf("-1\n");
    else
    printf("%d\n",ans);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值