思路:
问能到达那些位置,第一想到的就是广搜,问题是怎么搜。
1. 第一种, 普通队列因为可能多次到达某一点而体力状况不同,不能直接就用vis描述走过和没走过,从而想到用vis表示走过当前点的最大体力,搜索时与其进行比较,比它大时再push。
2. 第二种, 用优先级队列每次选取走过点中体力剩余体力最大的点更新,可以避免重复的情况,并且效率更高。
优先级队列代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
struct node
{
int x, y, val;
friend bool operator<(node a, node b)
{
return a.val < b.val;
}
};
int map[110][110];
int vis[110][110];
int nx[] = {0, 1, 0, -1}, ny[] = {1, 0, -1, 0};
void bfs(int n, int m, int stx, int sty, int mv)
{
priority_queue<node> q;
node t;
t.x = stx;
t.y = sty;
t.val = mv;
q.push(t);
memset(vis, 0, sizeof(vis));
vis[stx][sty] = 1;
while(!q.empty())
{
t = q.top();
q.pop();
for(int i = 0; i < 4; i++)
{
node to = t;
to.x += nx[i];
to.y += ny[i];
if(to.x < 1 || to.x > n || to.y < 1 || to.y > m)
continue;
if(map[to.x][to.y] == '#' || map[to.x][to.y] == 'E' || vis[to.x][to.y])
continue;
if(map[to.x][to.y] == '.' || map[to.x][to.y] == 'P')
to.val -= 1;
else if(map[to.x][to.y] == 'T')
to.val -= 2;
else if(map[to.x][to.y] == 'R')
to.val -= 3;
if(to.val < 0)
continue;
int flag = 0;
for(int j = 0; j < 4; j++)
{
int tx = to.x + nx[j];
int ty = to.y + ny[j];
if(tx >= 1 && tx <= n && ty >= 1 && ty <= m && map[to.x+nx[j]][to.y+ny[j]] == 'E') //注意越界
{
flag = 1;
break;
}
}
if(flag)
to.val = 0;
vis[to.x][to.y] = 1;
if(to.val) //!0时push
q.push(to);
}
}
}
int main(int argc, char const *argv[])
{
int t;
scanf("%d", &t);
while(t--)
{
int n, m, mv;
scanf("%d%d%d", &n, &m, &mv);
getchar();
int stx, sty;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
map[i][j] = getchar();
if(map[i][j] == 'Y')
{
stx = i;
sty = j;
}
}
getchar();
}
bfs(n, m, stx, sty, mv);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
// printf("%d ", vis[i][j]);
if(vis[i][j] == 0 || map[i][j] == 'Y' || map[i][j] == 'P')
printf("%c", map[i][j]);
else
printf("*");
}
printf("\n");
}
printf("\n");
}
return 0;
}
状态标记
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
struct node
{
int x, y, val;
};
int map[110][110];
int vis[110][110];
int nx[] = {0, 1, 0, -1}, ny[] = {1, 0, -1, 0};
void bfs(int n, int m, int stx, int sty, int mv)
{
queue<node> q;
node t;
t.x = stx;
t.y = sty;
t.val = mv;
q.push(t);
memset(vis, -1, sizeof(vis));
vis[stx][sty] = mv;
while(!q.empty())
{
t = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
node to = t;
to.x += nx[i];
to.y += ny[i];
if(to.x < 1 || to.x > n || to.y < 1 || to.y > m)
continue;
if(map[to.x][to.y] == '#' || map[to.x][to.y] == 'E')
continue;
if(map[to.x][to.y] == '.' || map[to.x][to.y] == 'P')
to.val -= 1;
else if(map[to.x][to.y] == 'T')
to.val -= 2;
else if(map[to.x][to.y] == 'R')
to.val -= 3;
if(to.val < 0)
continue;
int flag = 0;
for(int j = 0; j < 4; j++)
{
int tx = to.x + nx[j];
int ty = to.y + ny[j];
if(tx >= 1 && tx <= n && ty >= 1 && ty <= m && map[to.x+nx[j]][to.y+ny[j]] == 'E')
{
flag = 1;
break;
}
}
if(flag)
to.val = 0;
if(to.val > vis[to.x][to.y])
{
vis[to.x][to.y] = to.val;
if(to.val)
q.push(to);
}
}
}
}
int main(int argc, char const *argv[])
{
int t;
scanf("%d", &t);
while(t--)
{
int n, m, mv;
scanf("%d%d%d", &n, &m, &mv);
getchar();
int stx, sty;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
map[i][j] = getchar();
if(map[i][j] == 'Y')
{
stx = i;
sty = j;
}
}
getchar();
}
bfs(n, m, stx, sty, mv);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
if(vis[i][j] == -1 || map[i][j] == 'Y' || map[i][j] == 'P')
printf("%c", map[i][j]);
else
printf("*");
}
printf("\n");
}
printf("\n");
}
return 0;
}