L3-037 夺宝大赛

夺宝大赛的地图是一个由 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.

所有点bfs(超时18分):

#include<iostream>
#include<queue>
#include<unordered_map>
#include<algorithm>
#include<cstring>
using namespace std;
#define PII pair<int,int>
const int INF = 0x3f3f3f3f, mod = 998244353;
const int N = 105;
int g[N][N], n, m,x,y;
int k,dist[N][N];
int endx, endy;
int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 };
int cnt,temp[N],ans=-1;
unordered_map<int,int>mp;
void bfs(int x, int y) {
	queue<PII>q;
	dist[x][y] = 0;
	q.push({ x,y });
	while (q.size()) {
		auto it = q.front();
        q.pop();
		for (int i = 0;i < 4;i++) {
			int xx = it.first + dx[i];
			int yy = it.second + dy[i];
			if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && dist[xx][yy] == -1&&g[xx][yy]) {
				dist[xx][yy] = dist[it.first][it.second] + 1;
				q.push({ xx,yy });
			}
		}
	}
}
signed main()
{
	scanf("%d %d",&n,&m);
	for (int i = 1;i <= n;i++) {
		for (int j = 1;j <= m;j++) {
			scanf("%d",&g[i][j]);
			if (g[i][j] == 2) {
				endx = i;
				endy = j;
			}
		}
	}
	scanf("%d",&k);
	while (k--) {
		scanf("%d %d",&y,&x);
		memset(dist, -1, sizeof dist);
		bfs(x, y);
        temp[++cnt]=dist[endx][endy];
		 mp[dist[endx][endy]]++;
	}
    int distance=1e9;
for(int i=1;i<=cnt;i++){
    if(distance>temp[i]&&mp[temp[i]]==1&&temp[i]>=0){
        distance=temp[i];
        ans=i;
    }
}
ans==-1? printf("No winner."):printf("%d %d",ans,temp[ans]);
	return 0;
}

 

 从终点bfs:

#include<bits/stdc++.h>
#include<unordered_map> 
#include<unordered_set>
using namespace std;
#define int long long //可能会超时 
#define PII pair<int,int>
const int INF = 0x3f3f3f3f, mod = 998244353;
const int N = 105,M=5005;
int g[N][N], n, m;
int x[M], y[M],dist[N][N];
int endx, endy, k, temp[M];
int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 };
unordered_map<int, int>mp;
queue<PII>q;
void bfs(int x, int y) {
	dist[x][y] = 0;
	q.push({ x,y });
	while (q.size()) {
		auto it = q.front();
		q.pop();
		for (int i = 0;i < 4;i++) {
			int xx = it.first + dx[i];
			int yy = it.second + dy[i];
			if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && dist[xx][yy] == -1&&g[xx][yy]==1) {
				dist[xx][yy] = dist[it.first][it.second] + 1;
				q.push({ xx,yy });
			}
		}
	}
}
signed main()
{
	ios::sync_with_stdio, cin.tie(0), cout.tie(0);
	memset(dist, -1, sizeof dist);
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		for (int j = 1;j <= m;j++) {
			cin >> g[i][j];
			if (g[i][j] == 2) {
				endx = i;
				endy = j;
			}
		}
	}
	cin >> k;
	for (int i = 1;i <= k;i++){
        cin >> y[i] >> x[i];
    }
	bfs(endx, endy);
	for (int i = 1;i <= k;i++) {
		temp[i] = dist[x[i]][y[i]];
		mp[temp[i]]++;
	}
	int ans1 = -1, ans2 = 1e9;
	for (int i = 1;i <= k;i++) {
		if (mp[temp[i]] == 1&&temp[i] < ans2&&temp[i]>=0) {
			ans2 = temp[i];
			ans1 = i;
		}
	}
	ans1 == -1 ? cout << "No winner." : cout << ans1 << ' ' << ans2;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值