FZU1491 机器人测试
Problem Description 题目链接
为了测试我们的足球机器人的性能,我们设计如下的测试方法:
将一个机器人放在一个n*n的矩形阵列的某个格子中,它每次可以向与它所处的格子相邻的4个格子中的任何一个移动。
在这个阵列的一些格子中,摆放着能量,机器人希望能够得到这些能量。但是,这个阵列中存在着两种障碍物,一种障碍物使得机器人无法向前移动进入这个格子;第二种障碍物机器人虽然可以通过,但是,通过这样一个障碍物的时候,它先前所吃到的所有的能量都将消失。你的任务是,对于给定的一个阵列以及它的描述,计算出这个机器人所能够获得的最大能量值。
Input
本题有多组输入数据,你必须处理到EOF为止
输入数据的第一行表示输入矩阵的维数n,接下来n行,每行有n个元素,给出一个n*n的矩阵(n<=1000)。这个矩阵中,0表示这个格子上什么都没有,-1是机器人开始的位置,-2表示的是第一种障碍物,-3表示的是第2种障碍物。其他非负整数值表示的是能量的数值。
Output
输出仅一行,表示机器人所能获得的最大能量。
我们保证最后结果在[0, 230]的范围内。
Sample Input
4 10000 -2 0 0 -2 1 -1 0 -3 -3 0 0 1000 -3 0 0
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);
}
}