小雅文给推荐了一个杭电上的题,跳过题目看样例就知道是个BFS走地图……看到样例输出当时我就想骂人。先给出题目。
题目意思简介:勇者从左上角(0,0)出发,目标是右下角(n-1,m-1)。路上三种类型的点,'.'空地,数字表示有一个怪物,X就是障碍了。其中,怪物有血量1-9,表示勇者移动到这个格子之后还需要花费1-9的时间来击败怪物。距离‘.9.‘那么从左边的'.'出发,移动到第二格时间为1,打败怪物时间到10,然后再移动到右边时间为11.
求勇者从左上到右下的最短时间,并且输出路径。
算法 :BFS+优先队列
基本用不着分析可以得到的算法,就是coding的问题了,太久没写也是写的漏洞百出……自己一向在ACM比赛代码里不喜欢STL,于是果断手写了堆实现,还是挺简单的。之于输出格式,我想说!我讨厌输出路径!
#include
#include
#include
const int N = 105;
int n, m;
char map[N][N];
bool visited[N][N];
int dir[4][2] = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}}; //S E N W
int head, tail;
struct node
{
int x, y;
int v;
};
node que[N*N];
node road[N][N];
node out[N*N];
bool finded;
inline void init()
{
for(int i = 0; i < n; i ++)
{
scanf("%s", map[i]);
}
memset(visited, false, sizeof( visited ));
}
void heap(int e, int dic)
{
if( dic == 0 )
{
node temp = que[e];
while( e*2+1 < tail )
{
int nexte = e * 2 + 1;
if( que[nexte+1].v < que[nexte].v ) nexte ++;
if( que[nexte].v < temp.v )
{
que[e] = que[nexte];
e = nexte;
}
else break;
}
que[e] = temp;
}
else if ( dic == 1 )
{
node temp = que[e];
while( e > 0 )
{
int nexte = (e-1) / 2;
if( temp.v < que[nexte].v )
{
que[e] = que[nexte];
e = nexte;
}
else break;
}
que[e] = temp;
}
}
void output(int fx, int fy)
{
int L = -1;
node tp;
tp.x = fx;
tp.y = fy;
while( tp.x != -1 )
{
out[++L] = tp;
tp = road[tp.x][tp.y];
}
int time = 0;
for(int i = L-1; i >= 0; i -- )
{
int x = out[i].x;
int y = out[i].y;
time ++;
printf("%ds:(%d,%d)->(%d,%d)\n",time,out[i+1].x,out[i+1].y,x,y);
if( map[x][y] != '.' )
{
int j;
int cost = map[x][y] - '0';
for(j = 1; j <= cost; j ++)
{
time ++;
printf("%ds:FIGHT AT (%d,%d)\n", time, x, y);
}
}
}
}
void expend(node now, node &next, int &tail)
{
int x = next.x;
int y = next.y;
if( x < 0 || x >= n || y < 0 || y >= m ) return;
if( map[x][y] == 'X' ) return;
int value = 0;
if( map[x][y] == '.' ) value ++;
else value = map[x][y] - '0' + 1;
next.v = now.v + value;
if( !visited[x][y] )
{
road[x][y].x = now.x;
road[x][y].y = now.y;
visited[x][y] = true;
if( x == n-1 && y == m-1 )
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n", next.v);
output(x, y);
finded = true;
return;
}
que[tail++] = next;
heap(tail - 1, 1);
}
}
void bfs()
{
head = 0, tail = 1;
node now, end;
now.x = 0;
now.y = 0;
now.v = 0;
end.x = n -1;
end.y = m -1;
road[0][0].x = -1;
road[0][0].y = -1;
que[0] = now;
visited[0][0] = true;
finded = false;
while( head < tail )
{
now = que[head];
que[head] = que[tail-1];
tail --;
heap(0, 0);
node next;
for(int i = 0; i < 4; i ++)
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
expend(now, next, tail);
}
}
if( !finded )
{
puts("God please help our poor hero.");
}
puts("FINISH");
}
int main()
{
while( scanf("%d %d", &n, &m) != EOF )
{
init();
bfs();
}
return 0;
}