链接:https://www.nowcoder.com/acm/contest/118/A
来源:牛客网
题目描述
最近,喜爱ACM的PBY同学沉迷吃鸡,无法自拔,于是又来到了熟悉的ERANGEL。经过一番搜寻,PBY同学准备动身前往安全区,但是,地图中埋伏了许多LYB,PBY的枪法很差,希望你能够帮他找到一条路线,每次只能向上、下、左、右移动,尽可能遇到较少的敌人。
输入描述:
题目包含多组测试,请处理到文件结束;
第一行是一个整数n,代表地图的大小;
接下来的n行中,每行包含n个整数a,每个数字a代表当前位置敌人的数量;
1 < n <= 100,1 <= a <= 100,-1代表当前位置,-2代表安全区。
输出描述:
对于每组测试数据,请输出从当前位置到安全区所遇到最少的敌人数量,每个输出占一行。
示例1
输入
5
6 6 0 -2 3
4 2 1 2 1
2 2 8 9 7
8 1 2 1 -1
9 7 2 1 2
输出
9
示例2
输入
5
62 33 18 -2 85
85 73 69 59 83
44 38 84 96 55
-1 11 90 34 50
19 73 45 53 95
输出
173·
思路
从当前位置判断,相当前位置的上下左右走判断出走到下一步后遇到人最少的情况,进入队列并排序,队列首部一定是当前所遇人数最少的情况,
再把这一位置当做当前位置,重复上述操作直至第一个遇到终点时返回(第一个遇到终点的情况,一定是遇到人数最少的情况)
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int s[105][105];
int sx,sy;
int n;
int add[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct node
{
int x,y,num;
friend bool operator < (node a,node b)//重载“<”号
{
return a.num>b.num;
}
};
int dfs()
{
int i;
node d;
node per,cur;//per代表当前位置,cur代表下一步的位置
d.x=sx; d.y=sy; //d代表初始位置
d.num=0; //初始时,所遇人数为0
s[sx][sy]=-3; //把走过的位置都标记掉
priority_queue<node> q;//建一个可以重载运算符的队列
q.push(d);
while(!q.empty())
{
per=q.top();
q.pop();
for(i=0;i<4;i++)
{
cur.x=per.x+add[i][0];
cur.y=per.y+add[i][1];
if(s[cur.x][cur.y]==-2)
return per.num;//当遇到-2时到达终点
if(cur.x>0&&cur.x<=n&&cur.y>0&&cur.y<=n&&s[cur.x][cur.y]!=-3)
{
cur.num=per.num+s[cur.x][cur.y];//算出走到下一步一路上共遇到多少人
q.push(cur);//进入队列,因重载了“<”,队列会从小到大排
s[cur.x][cur.y]=-3;//将走过的地方标记掉
}
}
}
return 0;
}
int main()
{
int i,j,sum;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&s[i][j]);
if(s[i][j]==-1)
{
sx=i;sy=j;//找到起点
}
}
sum=dfs(); //运行函数dfs
printf("%d\n",sum);
}
return 0;
}