Treasure of the Chimp Island (BFS

Treasure of the Chimp Island

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 228 Accepted Submission(s): 91

Problem Description
Bob Bennett, the young adventurer, has found the map to the treasure of the Chimp Island, where the ghost zombie pirate LeChimp, the infamous evil pirate of the Caribbeans has hidden somewhere inside the Zimbu Memorial Monument (ZM 2). ZM 2 is made up of a number of corridors forming a maze. To protect the treasure, LeChimp has placed a number of stone blocks inside the corridors to block the way to the treasure. The map shows the hardness of each stone block which determines how long it takes to destroy the block. ZM 2 has a number of gates on the boundary from which Bob can enter the corridors. Fortunately, there may be a pack of dynamites at some gates, so that if Bob enters from such a gate, he may take the pack with him. Each pack has a number of dynamites that can be used to destroy the stone blocks in a much shorter time. Once entered, Bob cannot exit ZM 2 and enter again, nor can he walk on the area of other gates (so, he cannot pick more than one pack of dynamites).

The hardness of the stone blocks is an integer between 1 and 9, showing the number of days required to destroy the block. We neglect the time required to travel inside the corridors. Using a dynamite, Bob can destroy a block almost immediately, so we can ignore the time required for it too. The problem is to find the minimum time at which Bob can reach the treasure. He may choose any gate he wants to enter ZM 2.
 

Input
The input consists of multiple test cases. Each test case contains the map of ZM 2 viewed from the above. The map is a rectangular matrix of characters. Bob can move in four directions up, down, left, and right, but cannot move diagonally. He cannot enter a location shown by asterisk characters (*), even using all his dynamites! The character ($) shows the location of the treasure. A digit character (between 1 and 9) shows a stone block of hardness equal to the value of the digit. A hash sign (#) which can appear only on the boundary of the map indicates a gate without a dynamite pack. An uppercase letter on the boundary shows a gate with a pack of dynamites. The letter A shows there is one dynamite in the pack, B shows there are two dynamite in the pack and so on. All other characters on the boundary of the map are asterisks. Corridors are indicated by dots (.). There is a blank line after each test case. The width and the height of the map are at least 3 and at most 100 characters. The last line of the input contains two dash characters (--).
 

Output
For each test case, write a single line containing a number showing the minimum number of days it takes Bob to reach the treasure, if possible. If the treasure is unreachable, write IMPOSSIBLE.
 

Sample Input
*****#*********
*.1....4..$...*
*..***..2.....*
*..2..*****..2*
*..3..******37A
*****9..56....*
*.....******..*
***CA**********

*****
*$3**
*.2**
***#*

--
 

Sample Output
1
IMPOSSIBLE
 

这个题是一个不错的搜索题,要注意搜索时的状态,还要注意一下输入的技巧

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <stdio.h>
#include <vector>
#include <queue>
#include <utility>
typedef long long ll;
using namespace std;
int N, M, min_time;
int a[105][105][30];//状态数组,第三维是携带炸弹数量.
string map[105];
int dir[4][2] = {{-1,0}, {0,1}, {1,0}, {0,-1}};//direction
struct node {
    int x, y;
    int k, time;
    bool operator < (const node& n) const{
        return n.time < this->time;
    }
};
bool judge(int x, int y) {
    if (x < 0 || x >= N || y < 0 || y >= M || map[x][y] == '*')
        return 0;
    return 1;
}

void bfs() {
    memset(a, -1, sizeof(a));
    priority_queue<node> que;
    node first;
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < M; ++j) {
            if (map[i][j] == '#') {
                first.x = i, first.y = j, first.k = 0, first.time = 0;
                map[i][j]='*';
                que.push(first);
            }
            if (map[i][j] >= 'A' && map[i][j] <= 'Z') {
                first.x = i, first.y = j, first.k = map[i][j] - 'A' + 1, first.time = 0;
                map[i][j]='*';
                que.push(first);
            }
        }
    
    while (!que.empty()) {
        node cur = que.top(), next;
        que.pop();
        for (int i = 0; i < 4; ++i) {
            next.x = cur.x + dir[i][0];
            next.y = cur.y + dir[i][1];
            if (!judge(next.x, next.y))
                continue;
            
            if (map[next.x][next.y] == '.') {
                next.k = cur.k;
                    //检查,带k个炸药包,是否在x,y点经过,或是没有之前的走法优
                if (a[next.x][next.y][next.k] == -1 || a[next.x][next.y][next.k] > cur.time) {
                    next.time = cur.time;
                    a[next.x][next.y][next.k] = cur.time;
                    que.push(next);
                }
            } else if (map[next.x][next.y] >= '1' && map[next.x][next.y] <= '9') {
                    //炸掉
                if (cur.k >= 1 && (a[next.x][next.y][cur.k-1] == -1 || a[next.x][next.y][cur.k-1] > cur.time)) {
                    next.time = cur.time;
                    a[next.x][next.y][cur.k - 1] = cur.time;
                    next.k = cur.k -1;
                    que.push(next);
                }
                    //不炸
                if (a[next.x][next.y][cur.k] == -1 || a[next.x][next.y][cur.k] > cur.time + (map[next.x][next.y] - '0')) {
                    next.time = cur.time + (map[next.x][next.y] - '0');
                    next.k = cur.k;
                    a[next.x][next.y][next.k] = cur.time + (map[next.x][next.y] - '0');
                    que.push(next);
                }
            } else if (map[next.x][next.y] == '$' && cur.time < min_time) {
                min_time = cur.time;
            }
        }
    }
}
int main() {
    while (getline(cin, map[0]) && map[0][0] != '-') {
        int i = 1;
        while (getline(cin, map[i]) && map[i++].size() != 0);
        N = i-1;
        M = static_cast<int>(map[0].size());
        min_time = INT_MAX;
        bfs();
        if (min_time == INT_MAX)
            cout << "IMPOSSIBLE" << endl;
        else
            cout << min_time << endl;
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值