POJ 3346 && HDU 2416 Treasure of the Chimp Island(bfs)

470 篇文章 3 订阅
125 篇文章 0 订阅

Description
一个n*m的地图,.可以走,*不能走,起点在四周,每一个起点有一定数量的炸弹,#表示该起点没有炸弹,起点是一个字母则表示该起点有与该字母在字母表中位置相同数量的炸弹,在地图中数字表示该处有墙,有两种方案走过该点,一是多花费和该数字一样的时间去把墙挖倒,二是用一个炸弹瞬间炸穿墙,¥表示该处有钱,问从起点走到¥处的最短时间
Input
多组用例,每组用例输入一个字符矩阵表示该地图,相邻两组用例用空行隔开,以”–”结束输入,矩阵行列数不超过100
Output
输出起点集合到终点的最短用时,如果不可达则输出“IMPOSSIBLE”
Sample Input
这里写图片描述
Sample Output
1
IMPOSSIBLE
Solution
把一个点拆成27个点分别记录到该点还剩i个炸弹的最短用时(0<=i<=26),然后bfs即可,具体操作看代码
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 111
char s[maxn][maxn];
struct node
{
    int x,y,num;
};
int n,m,ex,ey,t[maxn][maxn][27],vis[maxn][maxn][27];
int dx[]={-1,0,1,0};
int dy[]={0,-1,0,1};
void bfs()
{
    queue<node>que;
    node now,temp;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            for(int k=0;k<27;k++)
                t[i][j][k]=INF,vis[i][j][k]=0;
            if(s[i][j]=='$')ex=i,ey=j;
            else if(s[i][j]=='#'||s[i][j]>='A'&&s[i][j]<='Z')
            {
                now.x=i,now.y=j;
                if(s[i][j]=='#')now.num=0;
                else now.num=s[i][j]-'A'+1;
                s[i][j]='*',t[i][j][now.num]=0,vis[i][j][now.num]=1;
                que.push(now);
            }   
        }
    while(!que.empty())
    {
        now=que.front();
        que.pop();
        int x=now.x,y=now.y,num=now.num;
        vis[x][y][num]=0;
        for(int i=0;i<4;i++)
        {
            int xx=x+dx[i],yy=y+dy[i];
            temp.x=xx,temp.y=yy,temp.num=num;
            if(xx<0||xx>=n||yy<0||yy>=m||s[xx][yy]=='*')continue;
            if((s[xx][yy]=='.'||s[xx][yy]=='$')&&t[xx][yy][num]>t[x][y][num])
            {
                t[xx][yy][num]=t[x][y][num];
                if(!vis[xx][yy][num])vis[xx][yy][num]=1,que.push(temp);
            }
            else if(s[xx][yy]>='1'&&s[xx][yy]<='9')
            {
                int cnt=s[xx][yy]-'0';
                if(t[xx][yy][num]>t[x][y][num]+cnt)
                {
                    t[xx][yy][num]=t[x][y][num]+cnt;
                    if(!vis[xx][yy][num])vis[xx][yy][num]=1,que.push(temp);
                }
                if(num&&t[xx][yy][num-1]>t[x][y][num])
                {
                    t[xx][yy][num-1]=t[x][y][num];
                    temp.num--;
                    if(!vis[xx][yy][num-1])vis[xx][yy][num-1]=1,que.push(temp);
                }
            }
        }
    }
    int ans=INF;
    for(int i=0;i<27;i++)ans=min(ans,t[ex][ey][i]);
    if(ans==INF)printf("IMPOSSIBLE\n");
    else printf("%d\n",ans);    
}
int main()
{
    while(gets(s[0]),s[0][0]!='-')
    {
        n=1;
        while(gets(s[n++]))
        {
            if(s[n-1][0]=='\0')
            {
                n--;
                break;
            }
        }
        m=strlen(s[0]);
        bfs();
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值