L3-1 夺宝大赛
分数 30
全屏浏览
切换布局
作者 陈越
单位 浙江大学
夺宝大赛的地图是一个由 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<iostream>
#include<cstring>
#include<unordered_map>
#include<vector>
#include<map>
using namespace std;
typedef pair<int ,int> PII;
unordered_map<int,vector<int> > ump_team;
unordered_map<int,vector<PII> > ump_xy;
#define x first
#define y second
const int N=150;
int d[N][N];
char g[N][N];
bool st[N][N];
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
PII q[N*N];
int n,m;
int x2,y2;
void bfs(int x1,int y1){
memset(d,-1,sizeof d);
int hh=0,tt=-1;
q[++tt]={x1,y1};
st[x1][y1]=true;
d[x1][y1]=0;
while(hh<=tt){
PII t=q[hh++];
for(int i=0;i<4;i++){
int xx=t.x+dx[i];
int yy=t.y+dy[i];
if(xx<1||xx>n||yy<1||yy>m)continue;
if(g[xx][yy]=='0'||st[xx][yy]||d[xx][yy]>=0)continue;
st[xx][yy]=true;
d[xx][yy]=d[t.x][t.y]+1;
q[++tt]={xx,yy};
}
}
}
int main(){
scanf("%d %d",&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')x2=i,y2=j;
}
}
bfs(x2,y2);
//for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// cout<<d[i][j]<<' ';
// }
// cout<<"\n";
//}
int k;scanf("%d",&k);
for(int i=1;i<=k;i++){
int x1,y1;scanf("%d %d",&y1,&x1);
int t=d[x1][y1];
// printf("x1=%d y1=%d d=%d\n",x1,y1,t);
ump_team[t].push_back(i);
ump_xy[t].push_back({x1,y1});
}
int min_distance=0x3f3f3f3f;
int winner_team=0x3f3f3f3f;
bool find=false;
for(auto it=ump_team.begin();it!=ump_team.end();it++){
int xx=it->first;
vector<int> vt =it->second;
vector<PII> pt =ump_xy[xx];
int x1=pt[0].x;
int y1=pt[0].y;
// printf("xx=%d pt=%d\n",xx,pt.size());
// printf("x1=%d y1=%d d=%d\n",x1,y1,d[x1][y1]);
if(pt.size()>1)continue;
if(d[x1][y1]>0&&d[x1][y1]<min_distance){
min_distance=xx;
winner_team=vt[0];
find=true;
}
}
if(find){
printf("%d %d",winner_team,min_distance);
}else{
printf("No winner.");
}
}
小丑了,差6分才175.。这题卡到我了。。没想到直接终点遍历,然后去重找最小单点即可,枯了,拿到这题就有200分了。枯死·-· 菜就多练 题做少了 没思路
全靠考后熬。。。