zoj 月赛

本文介绍了一款名为Wumpus的经典游戏,玩家需操控角色避开怪物和陷阱收集金币并安全返回起点。文章详细解析了游戏规则及得分计算方法,并提供了一个算法解决方案,通过BFS搜索来帮助玩家找到最优路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Wumpus

Time Limit: 2 Seconds      Memory Limit: 65536 KB

One day Leon finds a very classic game called Wumpus.The game is as follow.
Once an agent fell into a cave. The legend said that in this cave lived a kind of monster called Wumpus, and there were horrible pits which could lead to death everywhere. However, there were also a huge amount of gold in the cave. The agent must be careful and sensitive so that he could grab all of the gold and climb out of the cave safely.

The cave can be regarded as a n*n board. In each square there could be a Wumpus, a pit, a brick of gold, or nothing. The agent would be at position (0,0) at first and headed right.(As the picture below)

Wumpus1
For each step, there are six possible movements including going forward, turning left, turning right, shooting, grabbing the gold, and climbing out of the cave. If the agent steps into a square containing a pit or Wumpus, he will die. When the agent shoots, the Wumpus in front of him will die. The goal of the agent is to grab all of the gold and return to the starting position and climb out(it's OK if any Wumpus is still living).When a brick of gold is grabbed successfully, you will gain 1000 points. For each step you take, you will lose 10 points.

Your job is to help him compute the highest point he can possibly get.

For the purpose of simplification, we suppose that there is only one brick of gold and the agent cannot shoot the Wumpus.

If there is a pit at (0, 0), the agent dies immediately. There will not be a Wumpus at (0, 0).

Input

There are multiple cases. The first line will contain one integer k that indicates the number of cases.

For each case:
The first line will contain one integer n (n <= 20).
The following lines will contain three integers, each line shows a position of an object. The first one indicates the type of the object. 1 for Wumpus, 2 for pit and 3 for gold. Then the next two integers show the x and y coordinates of the object.
The input end with -1 -1 -1. (It is guaranteed that no two things appear in one position.)

Output

The output contains one line with one integer, which is the highest point Leon could possibly get. If he cannot finish the game with a non-negative score, print "-1".

Sample Input
2
3
1 1 1
2 2 0
3 2 2
-1 -1 -1
3
1 1 1
3 2 2
-1 -1 -1
Sample Output
850
870
Hint

For the sample 1, the following steps are taken:
turn left, forward, forward, turn right, forward, forward, grab, turn left, turn left, forward, forward, turn left, forward, forward, climb.
There are in all 15 steps, so the final score is 840. For the sample 2 , the path is as follow:

Wumpus2


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;
#define INF 0x3f3f3f3f
#define maxn 25

int a[maxn][maxn], X, Y, n, flag;
int go[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; /// up right down left
int d[maxn][maxn][4];

struct Grid
{
    int x, y, dire;
} g[2000];

bool judge(int x, int y)
{
    if(x>=0 && y>=0 && x<n && y<n && a[x][y]!=1 && a[x][y]!=2)
        return true;
    return false;
}

void bfs(int sx, int sy, int dire, int ex, int ey)
{
    queue<Grid> Q;
    Q.push(Grid {sx, sy, dire});
    memset(d, 0x3f, sizeof(d));
    d[sx][sy][dire] = 0;
    while(!Q.empty())
    {
        Grid t = Q.front();
        Q.pop();

        if(t.x == ex && t.y == ey)
            continue;

        for(int i=-1; i<3; i++)
        {
            int D = (t.dire + 4 + i) % 4;
            int xx = t.x + go[D][0];
            int yy = t.y + go[D][1];
            if(judge(xx, yy) && d[xx][yy][D] > d[t.x][t.y][t.dire] + 10 + abs(i) * 10)
            {
                d[xx][yy][D] = d[t.x][t.y][t.dire] + 10 + abs(i) * 10;
                Q.push(Grid {xx, yy, D});
            }
        }
    }
}

int main()
{
    int T, t, x, y;
    scanf("%d", &T);
    while(T--)
    {
        X = Y = -1;
        flag = 0;
        memset(a, 0, sizeof(a));
        scanf("%d", &n);
        while(scanf("%d%d%d", &t, &x, &y) && t!=-1)
        {
            if(t == 3)
                X = x, Y = y;
            a[x][y] = t;
        }

        int ans = INF;
        if(a[0][0] != 2 && X != -1)
        {
            bfs(0, 0, 1, X, Y);
            int Min1[4], Min2[4];
            fill(Min1, Min1+4, INF);
            fill(Min2, Min2+4, INF);

            for(int i=0; i<4; i++)
                Min1[i] = d[X][Y][i];

            for(int i=0; i<4; i++)
                if(Min1[i] != INF)
                {
                    flag = 1;
                    bfs(X, Y, i, 0, 0);
                    for(int j=0; j<4; j++)
                        Min2[i] = min(Min2[i], d[0][0][j]);
                    ans = min(ans, Min1[i] + Min2[i]);
                }
        }

        if(flag)
            printf("%d\n", 980 - ans);
        else
            printf("-1\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值