2018年北京信息科技大学第十届程序设计竞赛暨ACM选拔赛 A题题解

链接: https://www.nowcoder.com/acm/contest/118/A
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

最近,喜爱ACM的PBY同学沉迷吃鸡,无法自拔,于是又来到了熟悉的ERANGEL。经过一番搜寻,PBY同学准备动身前往安全区,但是,地图中埋伏了许多LYB,PBY的枪法很差,希望你能够帮他找到一条路线,每次只能向上、下、左、右移动,尽可能遇到较少的敌人。

输入描述:

题目包含多组测试,请处理到文件结束;
第一行是一个整数n,代表地图的大小;
接下来的n行中,每行包含n个整数a,每个数字a代表当前位置敌人的数量;
1 < n <= 100,1 <= a <= 100,-1代表当前位置,-2代表安全区。

输出描述:

对于每组测试数据,请输出从当前位置到安全区所遇到最少的敌人数量,每个输出占一行。

链接: https://www.nowcoder.com/acm/contest/118/A
来源:牛客网

示例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

思路:求从原点到目标点遇见最少的人数,利用BFS,以最短路径的方式,既然要求遇见最少的人数,每次应该是当前位置的周围有最少人数的位置入队,利用优先队列可以实现。

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 110;
const int INF  = 0x3f3f3f3f;
int mp[MAXN][MAXN];
int n;
int si,sj,ei,ej;
int dp[MAXN][MAXN];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
typedef pair<int,int> P;
bool used[MAXN][MAXN];
struct node {
	int x;
	int y;
	int val;
};
struct cmp{
    bool operator () (node f1, node f2) // 重载括号
    {
        return f1.val>=f2.val; 
    }
};
priority_queue<node,vector<node>,cmp > que;
void bfs(){
	int i,j;
	while(!que.empty()){
		node a = que.top();
		que.pop();
		i=a.x;
		j=a.y;
		used[i][j]=true;
		if(i==ei && j==ej){
			return ;
		}
		for(int k=0;k<4;k++){
			int di=i+dir[k][0];
			int dj=j+dir[k][1];
			if(di>=0 && di<n && dj>=0 && dj<n && used[di][dj]==false){
				dp[di][dj]=dp[i][j]+mp[di][dj];
				used[di][dj]=true;
				que.push((node){di,dj, dp[di][dj]});				
			}
		}
	}
}
void sovle(){
	while(!que.empty()){
		que.pop();
	}
	for (int i = 0; i <= n; ++i)
		for (int j = 0; j <= n; ++j) dp[i][j] = INF;
	memset(used,false,sizeof(used));
	dp[si][sj]=0;
	que.push((node){si,sj, 0});
	used[si][sj]=true;
	bfs();
	printf("%d\n",dp[ei][ej]+2);
}
int main(){
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				scanf("%d",&mp[i][j]);
				if(mp[i][j]==-1){
					si=i;
					sj=j;
				}
				if(mp[i][j]==-2){
					ei=i;
					ej=j;
				}
			}
		}
		sovle();
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/Rainbow_storm/article/details/80219420
今日推荐