L3-037 夺宝大赛

文章讨论了一个夺宝大赛问题,参赛队伍需要在地图上避开障碍物,以最快速度到达唯一的大本营,避免火拼。通过BFS算法计算每个队伍到达大本营的时间,找出最早到达且未发生火拼的队伍作为胜者。
摘要由CSDN通过智能技术生成

夺宝大赛的地图是一个由 n×m 个方格子组成的长方形,主办方在地图上标明了所有障碍、以及大本营宝藏的位置。参赛的队伍一开始被随机投放在地图的各个方格里,同时开始向大本营进发。所有参赛队从一个方格移动到另一个无障碍的相邻方格(“相邻”是指两个方格有一条公共边)所花的时间都是 1 个单位时间。但当有多支队伍同时进入大本营时,必将发生火拼,造成参与火拼的所有队伍无法继续比赛。大赛规定:最先到达大本营并能活着夺宝的队伍获得胜利。
假设所有队伍都将以最快速度冲向大本营,请你判断哪个队伍将获得最后的胜利。

输入格式:

输入首先在第一行给出两个正整数 m 和 n(2<m,n≤100),随后 m 行,每行给出 n 个数字,表示地图上对应方格的状态:1 表示方格可通过;0 表示该方格有障碍物,不可通行;2 表示该方格是大本营。题目保证只有 1 个大本营。
接下来是参赛队伍信息。首先在一行中给出正整数 k(0<k<m×n/2),随后 k 行,第 i(1≤i≤k)行给出编号为 i 的参赛队的初始落脚点的坐标,格式为 x y。这里规定地图左上角坐标为 1 1,右下角坐标为 n m,其中 n 为列数,m 为行数。注意参赛队只能在地图范围内移动,不得走出地图。题目保证没有参赛队一开始就落在有障碍的方格里。

输出格式:

在一行中输出获胜的队伍编号和其到达大本营所用的单位时间数量,数字间以 1 个空格分隔,行首尾不得有多余空格。若没有队伍能获胜,则在一行中输出 No winner.

输入样例 1:

5 7
1 1 1 1 1 0 1
1 1 1 1 1 0 0
1 1 0 2 1 1 1
1 1 0 0 1 1 1
1 1 1 1 1 1 1
7
1 5
7 1
1 1
5 5
3 1
3 5
1 4

输出样例 1:

7 6

样例 1 说明:

七支队伍到达大本营的时间顺次为:7、不可能、5、3、3、5、6,其中队伍 4 和 5 火拼了,队伍 3 和 6 火拼了,队伍 7 比队伍 1 早到,所以获胜。

输入样例 2:

5 7
1 1 1 1 1 0 1
1 1 1 1 1 0 0
1 1 0 2 1 1 1
1 1 0 0 1 1 1
1 1 1 1 1 1 1
7
7 5
1 3
7 1
1 1
5 5
3 1
3 5

输出样例 2:

No winner.

代码长度限制

16 KB

Java (javac)

时间限制

800 ms

内存限制

256 MB

其他编译器

时间限制

400 ms

内存限制

64 MB

栈限制

8192 KB

---------------------------------------------------------------------------------------------------------------------------------

开始的时候对每个对求一次 bfs() 从而得出每个点到大本营的距离。

结果超时,去找了一下别人的题解。

发现只要对大本营进行一次 bfs() 即可以得出每个点到大本营的距离。(orz 瓦达西哇好蠢啊💔)

然后就是怎么从一堆数中找到一个最小的且只有一个的那个数,输出:这个数是哪个队伍的 和  这个数  (实现这个大家可以按照自己的想法~~~)(写的时候卡这了)

俺滴代码:

#include<iostream>
#include<map>
#include<queue>
using namespace std;
struct node{
	int xt,yt;
};
int u,v,n,m;
int mp[111][111];
int ct[111][111];
int ans[10000];
int dx[4]={0,-1,0,1};
int dy[4]={-1,0,1,0};
void bfs(int x,int y){
	queue<node>q;
	q.push({x,y});
	while(!q.empty()){
		node n1=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			int xtp=n1.xt+dx[i];
			int ytp=n1.yt+dy[i];
			if(ct[xtp][ytp]||!mp[xtp][ytp]) continue;
			if(xtp<=0||xtp>n||ytp<=0||ytp>m) continue;
		    ct[xtp][ytp]=ct[n1.xt][n1.yt]+1;
		    q.push({xtp,ytp});
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=m;j++)
	 {
	 	scanf("%d",&mp[i][j]);
	 	if(mp[i][j]==2){
	 		u=i,v=j;
		 }
	 }
	 bfs(u,v); 
	int k; cin>>k;
	for(int i=1;i<=k;i++){
		int a,b;
		scanf("%d%d",&b,&a);
		if(ct[a][b]){
			if(ans[ct[a][b]]==0) ans[ct[a][b]]=i;
			else ans[ct[a][b]]=-1;
	    }
    }
    int flag=1;
    for(int i=1;i<10000;i++)
    {
    	if(ans[i]>0)
    	{
    		printf("%d %d",ans[i],i);
    		flag=0;
    		break;
		}
	}
	if(flag) printf("No winner.");
	  return 0;
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值