http://acm.hdu.edu.cn/showproblem.php?pid=1242
题意是从r找到a,路过.时间+1,路过x时间+2,#围墙,求最短的时间。
用a[n][m]保存位置,围墙为-1,.为1,x为2。用A*索搜计算出每一步的f值,在通过优先队列f最小的开始出队列,直到找到为止。
s为当前已用的时间。
h为预测到目标地点的时间下界。
f=s+h;
代码:
#include<iostream>
#include<queue>
using namespace std;
int _move[4][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }};
int b;
struct node
{
int f, s, h;
int x, y, step;
friend bool operator<(node n1, node n2)
{
return n2.f<n1.f;
}
};
int n, m,a[205][205];
int s_x, s_y, e_x, e_y;
int getH(int x,int y){
return abs(x - e_x) + abs(y - e_y);
}
int isOk(int x, int y){
if (x < 0 || x >= n || y < 0 || y >= m) return 0;
return 1;
}
void bfs(){
priority_queue<node> qu;
node now,temp;
now.x = s_x; now.y = s_y;
now.h = getH(s_x, s_y); now.s = 0;
now.f = now.h + now.s;
qu.push(now);
while (qu.size()>0)
{
now = qu.top(); qu.pop();
if (now.x == e_x&&now.y == e_y){
cout << now.s<<endl;
b = 1;
return;
}
a[now.x][now.y] = -1;
for (int i = 0; i < 4; i++){
temp.x = now.x + _move[i][0];
temp.y = now.y + _move[i][1];
if (isOk(temp.x, temp.y) && a[temp.x][temp.y] >= 0){
temp.s = now.s + a[temp.x][temp.y];
temp.h = getH(temp.x,temp.y);
temp.f = temp.s + temp.h;
qu.push(temp);
}
}
}
}
int main(){
while (cin>>n>>m)
{
b = 0;
char temp;
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
cin >> temp;
if (temp == '.') a[i][j] = 1;
else if (temp == 'x') a[i][j] = 2;
else if (temp == 'r'){
a[i][j] = 1;
e_x = i;
e_y = j;
}
else if (temp == 'a'){
a[i][j] = 0;
s_x = i;
s_y = j;
}
else
{
a[i][j] = -1;
}
}
}
bfs();
if (!b) cout << "Poor ANGEL has to stay in the prison all his life." << endl;
}
}