Acdream 1191 Dragon Maze bfs

Dragon Maze

Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
Problem Description

You are the prince of Dragon Kingdom and your kingdom is in danger of running out of power. You must find power to save your kingdom and its people. An old legend states that power comes from a place known as Dragon Maze. Dragon Maze appears randomly out of nowhere without notice and suddenly disappears without warning. You know where Dragon Maze is now, so it is important you retrieve some power before it disappears.

Dragon Maze is a rectangular maze, an N×M grid of cells. The top left corner cell of the maze is (0, 0) and the bottom right corner is(N-1, M-1). Each cell making up the maze can be either a dangerous place which you never escape after entering, or a safe place that contains a certain amount of power. The power in a safe cell is automatically gathered once you enter that cell, and can only be gathered once. Starting from a cell, you can walk up/down/left/right to adjacent cells with a single step.

Now you know where the entrance and exit cells are, that they are different, and that they are both safe cells. In order to get out of Dragon Maze before it disappears, you must walk from the entrance cell to the exit cell taking as few steps as possible.

If there are multiple choices for the path you could take, you must choose the one on which you collect as much power as possible in order to save your kingdom.

Input

The first line of the input gives the number of test cases, T(1 ≤ T ≤ 30)T test cases follow.

Each test case starts with a line containing two integers N and M(1 ≤ N, M ≤ 100), which give the size of Dragon Maze as described above.

The second line of each test case contains four integers enx, eny, exx, exy(0 ≤ enx, exx < N, 0 ≤ eny, exy < M), describing the position of entrance cell (enx, eny) and exit cell (exx, exy).

Then N lines follow and each line has M numbers, separated by spaces, describing the N×M cells of Dragon Maze from top to bottom.

Each number for a cell is either -1, which indicates a cell is dangerous, or a positive integer, which indicates a safe cell containing a certain amount of power.

Output

For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1).

If it's possible for you to walk from the entrance to the exit, y should be the maximum total amount of power you can collect by taking the fewest steps possible.

If you cannot walk from the entrance to the exit, y should be the string "Mission Impossible." (quotes for clarity).

Sample Input
2
2 3
0 2 1 0
2 -1 5
3 -1 6
4 4
0 2 3 2
-1 1 1 2
1 1 1 1
2 -1 -1 1
1 1 1 1
Sample Output
Case #1: Mission Impossible.
Case #2: 7
Source
codejam
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
 
using namespace std;
 
#define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define CLR(vis,pos) memset(vis,pos,sizeof(vis))
#define PI acos(-1.0)
#define INF 0x7FFFFFFF
#define LINF 1000000000000000000LL
#define eps 1e-8
 
typedef long long ll;
 
int dx[4]={-1,1,0,0};
int dy[4]={0,0,1,-1};
 
int n,m;
int a[123][123];
pair<int,int> x,y;
int ans;
int vis[123][123];
int step[123][123],val[123][123];
struct node{
    int x,y;
};
 
int bfs(int i,int j){
    if(a[i][j]==-1) return -1;
    node tmp;
    tmp.x=i,tmp.y=j;
    queue<node> q;
    q.push(tmp);
    step[tmp.x][tmp.y]=1;
    val[tmp.x][tmp.y]=a[tmp.x][tmp.y];
    while(!q.empty()){
        tmp=q.front();
        q.pop();
        vis[tmp.x][tmp.y]=1;
        node p;
        REP(k,4){
            p.x=tmp.x+dx[k];
            p.y=tmp.y+dy[k];
            if( (step[p.x][p.y]<0 || step[p.x][p.y]>=step[tmp.x][tmp.y]+1) && a[p.x][p.y]!=-1 && !vis[p.x][p.y]){
                if(step[p.x][p.y]<0)
                    q.push(p);
                step[p.x][p.y]=step[tmp.x][tmp.y]+1;
                val[p.x][p.y]=max(val[p.x][p.y],a[p.x][p.y]+val[tmp.x][tmp.y]);
            }
        }
    }
    return val[y.first][y.second];
}
 
 
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int T;
    scanf("%d",&T);
    REP(cas,T){
        scanf("%d%d",&n,&m);
        scanf("%d%d%d%d",&x.first,&x.second,&y.first,&y.second);
        x.first++,x.second++,y.first++,y.second++;
        CLR(a,-1);
        FOR(i,1,n){
            FOR(j,1,m){
                scanf("%d",&a[i][j]);
            }
        }
        CLR(vis,0),CLR(val,-1),CLR(step,-1);
        ans=bfs(x.first,x.second);
        if(ans==-1){
            printf("Case #%d: Mission Impossible.\n",cas+1);
        }
        else{
            printf("Case #%d: %d\n",cas+1,ans);
        }
 
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是对DFS、BFS和UCS的介绍: DFS(深度优先搜索):总是扩展最深层的节点,使用的是LIFO队列,即使用的是stack栈。DFS在生成节点时做的goal test,因此在搜索树中,DFS总是沿着最深的路径搜索,直到找到目标状态或者无法继续搜索为止。DFS的优点是空间复杂度低,但是可能会陷入局部最优解。 BFS(广度优先搜索):总是扩展最浅层的节点,使用的是FIFO队列,即使用的是queue队列。BFS在扩展节点时做的goal test,因此在搜索树中,BFS总是沿着最浅的路径搜索,直到找到目标状态或者无法继续搜索为止。BFS的优点是可以找到最优解,但是空间复杂度较高。 UCS(最佳优先搜索):总是扩展当前代价最小的节点,使用的是priority queue优先队列。UCS在扩展节点时做的goal test,因此在搜索树中,UCS总是沿着代价最小的路径搜索,直到找到目标状态或者无法继续搜索为止。UCS的优点是可以找到最优解,且可以在frontier集中记录所有合适的解,但是空间复杂度较高。 以下是对DFS、BFS和UCS的演示: 假设我们要在一个迷宫中找到从起点到终点的最短路径,其中1表示墙,0表示可以通过的路。迷宫如下所示: ``` 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 ``` 我们可以使用DFS、BFS和UCS来寻找最短路径。其中DFS使用stack栈,BFS使用queue队列,UCS使用priority queue优先队列。具体实现可以参考以下代码: ```python # DFS def dfs(maze, start, end): stack = [(start, [start])] visited = set() while stack: node, path = stack.pop() if node == end: return path if node not in visited: visited.add(node) for neighbor in get_neighbors(maze, node): stack.append((neighbor, path + [neighbor])) return None # BFS def bfs(maze, start, end): queue = [(start, [start])] visited = set() while queue: node, path = queue.pop(0) if node == end: return path if node not in visited: visited.add(node) for neighbor in get_neighbors(maze, node): queue.append((neighbor, path + [neighbor])) return None # UCS def ucs(maze, start, end): queue = [(0, start, [start])] visited = set() while queue: cost, node, path = heapq.heappop(queue) if node == end: return path if node not in visited: visited.add(node) for neighbor in get_neighbors(maze, node): new_cost = cost + 1 heapq.heappush(queue, (new_cost, neighbor, path + [neighbor])) return None # 获取邻居节点 def get_neighbors(maze, node): neighbors = [] row, col = node if row > 0 and maze[row-1][col] == 0: neighbors.append((row-1, col)) if row < len(maze)-1 and maze[row+1][col] == 0: neighbors.append((row+1, col)) if col > 0 and maze[row][col-1] == 0: neighbors.append((row, col-1)) if col < len(maze[0])-1 and maze[row][col+1] == 0: neighbors.append((row, col+1)) return neighbors ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值