★实验任务
正如你所知道的 s_sin 是一个贪玩的不得了的小 P 孩 QAQ,你也知道他最近很喜欢玩一
个叫做太阳帝国的原罪的策略游戏去年他已经和疯狂的 AI 交战了整整一年。而现在,战斗
的序幕又要拉开了。
在某个星球上,该星球由 n*m 个方格组成,每个方格中可能为 boss, s_sin,障碍,道
路,小怪。 s_sin 想要去打爆 boss,假设他可以秒杀 boss,现在他的任务只需要到达 boss
所在的位置。如果 s_sin 想要到达某个方格,但方格中有小怪,那么必须打死小怪,才能到
达这个方格。假设 s_sin 只能向上、下、左、右移动一个格子,移动一步用时 1 个时间单位,
杀死小怪也用 1 个时间单位。假设 s_sin 很强壮,可以杀死所有小怪。
试计算 s_sin 到达 boss 位置至少需要多少时间。注意:障碍时不能通过的。
★数据输入
输入第一行为两个正整数 n, m (1 < =n, m< =100), 表示该地图有 n 行 m 列。
接下来 n 行,每行 m 个字符:“ .”代表道路 , “ a”代表 boss , “ r”代表 s_sin ,
“ #”代表障碍,“ x”代表小怪。
★数据输出
如果 s_sin 能到达 boss 位置则输出所需的最少时间。如果无法达到,则输出-1
输入示例 输出示例
7 8 13
#.#####.
#.a#..r.
#..#x...
..#..#.#
#include<cstdio>
#include<queue>
using namespace std;
struct node
{
int x,y,dis;
bool operator<(const node &b)const{
return dis>b.dis;}
};
priority_queue<node> q;
const int N=105;
char G[N][N];
bool vis[N][N];
int n,m;
int get_value(const node &cur)
{
switch(G[cur.y][cur.x])
{
case '.':
case 'a':
return 1;
case 'x':
return 2;
}
return 0;
}
void move_out(const node &cur)
{
int i,tmp[]={0,0,1,-1};
node next;
for(i=0;i<4;++i)
{
next.x=cur.x+tmp[i],next.y=cur.y+tmp[3-i];
if(next.y<0||next.y>=n||next.x<0||next.x>=m)continue;
if(!vis[next.y][next.x]&&G[next.y][next.x]!='#')
{
next.dis=cur.dis+get_value(next);
q.push(next);
}
vis[next.y][next.x]=true;
}
}
int search_map(const node &start,const node&end)
{
node cur;
vis[start.y][start.x]=true;
q.push(start);
while(!q.empty())
{
cur=q.top();q.pop();
// printf("y->%d x->%d\n",cur.y,cur.x);
if(cur.x==end.x&&cur.y==end.y)return cur.dis;
move_out(cur);
}
return -1;
}
int main()
{
int i,j,flag;
node start,end;
scanf("%d %d",&n,&m);
for(i=0;i<n;++i){
scanf("%s",G[i]);
}
for(i=0,flag=0;i<n;++i)
for(j=0;j<m;++j)
{
if(flag==2)break;
if(G[i][j]=='r')start.x=j,start.y=i,start.dis=0,flag++;
if(G[i][j]=='a')end.x=j,end.y=i,flag++;
}
printf("%d\n",search_map(start,end));
}