夺宝大赛的地图是一个由 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.
#include <bits/stdc++.h>
using namespace std;
//终点只有一个,反向BFS
//int dist[N][N] 存储距离,初始化为-1,免去bool st[N][N]
//通过条件判断要筛选的容器的值,不去创建新的容器
typedef pair<int, int> PII;
const int N = 150;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int dist[N][N];
char g[N][N];
int n,m;
PII treasure;
void bfs(int x, int y) {
queue<PII> q;
q.push({x, y});
dist[x][y] = 0;
while (!q.empty()) {
auto a = q.front();
int cx = a.first;
int cy = a.second;
q.pop();
for (int i = 0; i < 4; ++i) {
int nx = cx + dx[i];
int ny = cy + dy[i];
if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
if (g[nx][ny] == '0' || dist[nx][ny] != -1) continue;
q.push({nx, ny});
dist[nx][ny] = dist[cx][cy] + 1;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
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')
treasure = {i, j};
dist[i][j] = -1;
}
}
bfs(treasure.first, treasure.second);
int k;
cin>>k;
unordered_map<int, vector<int> > time_to_teams;
for (int i = 1; i <= k; ++i) {
int x, y;
cin>>y>>x;
if (dist[x][y] != -1) {
time_to_teams[dist[x][y]].push_back(i);
}
}
int winner = -1, min_time = 1e9;
for (auto it = time_to_teams.begin(); it != time_to_teams.end(); ++it) {
int time = it->first;
vector<int>& teams = it->second;
if (teams.size() == 1 && time < min_time) {
min_time = time;
winner = teams[0];
}
}
if (winner != -1)
cout<<winner<<" "<<min_time;
else
cout<<"No winner.";
return 0;
}