天梯赛 L3-1 夺宝大赛

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分了。枯死·-·  菜就多练   题做少了   没思路  

全靠考后熬。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值