正如你所知道的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
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........
13
1."."与'a'都是没哟停留时间的,但每走一次都需要1个单位时间,所以还是假设他们的权值为1
2.'x' 停留时间1个单位加上走需要一个单位时间,权值时间为2个单位
3.每次取出优先队列的首个元素,然后对它的上下左右点做判断,满足一定条件的点push到队列里,更新vis数组
#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));
}
做个小小优化
当“观察”取出点的上下左右中发现终点,则程序结束
#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;
}
int move_out(const node &cur,const node &end)
{
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);
if(next.x==end.x&&next.y==end.y)return next.dis;
q.push(next);
}
vis[next.y][next.x]=true;
}
return -1;
}
int search_map(const node &start,const node&end)
{
node cur;
int ans=-1;
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;
ans=move_out(cur,end);
if(ans>-1)return ans;
}
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));
}