FZU1491 机器人测试

Problem Description 题目链接

为了测试我们的足球机器人的性能,我们设计如下的测试方法:

将一个机器人放在一个n*n的矩形阵列的某个格子中,它每次可以向与它所处的格子相邻的4个格子中的任何一个移动。

在这个阵列的一些格子中,摆放着能量,机器人希望能够得到这些能量。但是,这个阵列中存在着两种障碍物,一种障碍物使得机器人无法向前移动进入这个格子;第二种障碍物机器人虽然可以通过,但是,通过这样一个障碍物的时候,它先前所吃到的所有的能量都将消失。你的任务是,对于给定的一个阵列以及它的描述,计算出这个机器人所能够获得的最大能量值。

FZU1491 机器人测试 Input

本题有多组输入数据,你必须处理到EOF为止

输入数据的第一行表示输入矩阵的维数n,接下来n行,每行有n个元素,给出一个n*n的矩阵(n<=1000)。这个矩阵中,0表示这个格子上什么都没有,-1是机器人开始的位置,-2表示的是第一种障碍物,-3表示的是第2种障碍物。其他非负整数值表示的是能量的数值。

FZU1491 机器人测试 Output

输出仅一行,表示机器人所能获得的最大能量。

我们保证最后结果在[0, 230]的范围内。

FZU1491 机器人测试 Sample Input

4 10000 -2 0 0 -2 1 -1 0 -3 -3 0 0 1000 -3 0 0

FZU1491 机器人测试 Sample Output

1000
 
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;

/*
    思路  第一步:因为-3会清空能量,一开始可以将-3和-2看成围墙,看看图中可以分割几块小图,类似LeetCode200计算岛屿数量,并给岛屿编号
          第二步:从机器人出发 再一次BFS求所能经过的最大值,-3看成通路
*/

int N, map[1005][1005], visit[1005][1005], val[1000005], num, res;
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};

//边界和访问检查
bool check(int x, int y)
{
    if (x < 1 || y < 1 || x > N || y > N || visit[x][y])
        return false;
    return true;
}

struct Pos
{
    int x, y;
};

//第一次计算岛屿
void Bfs(int x, int y)
{
    Pos p;
    p.x = x;
    p.y = y;
    visit[x][y] = 1;
    if (map[x][y] > 0)
        val[num] = map[x][y];
    else
    {
        val[num] = 0;
    }
    map[x][y] = num;
    queue<Pos> q;
    q.push(p);
    while (!q.empty())
    {
        p = q.front();
        q.pop();
        for (int i = 0; i < 4; i++)
        {
            int _x = p.x + dir[i][0], _y = p.y + dir[i][1];
            if (check(_x, _y))
            {
                visit[_x][_y] = 1;
                //非墙
                if (map[_x][_y] >= -1)
                {
                    if (map[_x][_y] > 0)
                        val[num] += map[_x][_y];
                    map[_x][_y] = num;
                    Pos t;
                    t.x = _x;
                    t.y = _y;
                    q.push(t);
                }
            }
        }
    }
}

//第二次寻找最大值
void BfsSearchMax(int x, int y)
{
    Pos p;
    p.x = x;
    p.y = y;
    visit[x][y] = 1;
    res = 0;
    queue<Pos> q;
    q.push(p);
    while (!q.empty())
    {
        p = q.front();
        q.pop();
        for (int i = 0; i < 4; i++)
        {
            int _x = p.x + dir[i][0], _y = p.y + dir[i][1];
            if (check(_x, _y))
            {
                visit[_x][_y] = 1;
                //非墙
                if (map[_x][_y] != -2)
                {
                    if (map[_x][_y] > 0 && res < val[map[_x][_y]])
                        res = val[map[_x][_y]];
                    Pos t;
                    t.x = _x;
                    t.y = _y;
                    q.push(t);
                }
            }
        }
    }
}

int main()
{
    while (scanf("%d", &N) != EOF)
    {
        int sx = 0, sy = 0;
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++)
            {
                scanf("%d", &map[i][j]);
                visit[i][j] = 0;
                if (map[i][j] == -1)
                {
                    sx = i;
                    sy = j;
                }
            }
        //num 地图编号 同一块小图编号相同
        num = 1;
        for (int i = 1; i <= N; i++)
        {
            for (int j = 1; j <= N; j++)
            {
                //说明未访问
                if (visit[i][j] == 0 && map[i][j] >= -1)
                {
                    Bfs(i, j);
                    num++;
                }
            }
        }
        memset(visit, 0, sizeof(visit));
        BfsSearchMax(sx, sy);
        printf("%d\n", res);
    }
}
PS:BFS能A题,但是我用DFS出现RuntimError不知道有没有大佬看看哪里出错了
#include <stdio.h>
#include <string.h>

int N, map[1005][1005], visit[1005][1005], val[1000001], num, res;
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};

//边界和访问检查
bool check(int x, int y)
{
    if (x < 1 || y < 1 || x > N || y > N || visit[x][y])
        return false;
    return true;
}

//计算池塘的Val 此时-2 -3当作墙
void dfs(int x, int y)
{
    for (int i = 0; i < 4; i++)
    {
        int _x = x + dir[i][0], _y = y + dir[i][1];
        if (check(_x, _y))
        {
            visit[_x][_y] = 1;
            if (map[_x][_y] >= -1) //说明可以访问
            {
                if (map[_x][_y] > 0)
                    val[num] += map[_x][_y];
                map[_x][_y] = num;
                dfs(_x, _y);
            }
        }
    }
}

//计算最大值 此时-3能通过
void dfsMax(int x, int y)
{
    for (int i = 0; i < 4; i++)
    {
        int _x = x + dir[i][0], _y = y + dir[i][1];
        if (check(_x, _y))
        {
            visit[_x][_y] = 1;
            //说明可以通过
            if (map[_x][_y] != -2)
            {
                if (map[_x][_y] > 0 && res < val[map[_x][_y]])
                    res = val[map[_x][_y]];
                dfsMax(_x, _y);
            }
        }
    }
}

int main()
{
    while (scanf("%d", &N) != EOF)
    {
        int sx=0, sy=0;
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++)
            {
                scanf("%d", &map[i][j]);
                visit[i][j] = 0;
                if (map[i][j] == -1)
                {
                    sx = i;
                    sy = j;
                }
            }
        //初始化NUM
        num = 1;
        for (int i = 1; i <= N; i++)
        {
            for (int j = 1; j <= N; j++)
            {
                //说明未访问
                if (visit[i][j] == 0 && map[i][j] >= -1)
                {
                    if (map[i][j] > 0)
                        val[num] = map[i][j];
                    else
                    {
                        val[num] = 0;
                    }
                    map[i][j] = num;
                    visit[i][j] = 1;
                    dfs(i, j);
                    num++;
                }
            }
        }
        memset(visit, 0, sizeof(visit));
        res = 0;
        visit[sx][sy] = 1;
        dfsMax(sx, sy);
        printf("%d\n", res);
    }
}