L3-1 夺宝大赛-2024天梯赛(内存超限解决方法)

题目

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

分析

计算最短路径,用BFS来做。
刚开始的思路是对于每一组输入士兵的起点分别dfs计算到大本营的最短路径,那么结果就是这样,内存超限了最后两个点。
在这里插入图片描述
解决方法就是从大本营开始bfs地图上每一个能够到达的点,到达某点后记录下到达该点的最短距离,bfs第一次到达该点一定是最短距离。

代码

#include<iostream>
#include<queue>
#include<algorithm>
#include<unordered_map>
using namespace std;
int n,m;
int k;
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int mp[110][110];
struct node{
    int x,y,val;
};
struct node2{
    int id,val;
}step[1100];
bool cmp(node2 a,node2 b){
    return a.val<b.val;
}
int vis[110][110];
void bfs(int x,int y){
    queue<node>q;
    q.push({x,y,0});
    while(!q.empty()){
        node t=q.front();
        // cout<<vis[t.x][t.y]<<endl;
        q.pop();
        for(int i=0;i<4;i++){
            int nx=t.x+dir[i][0];
            int ny=t.y+dir[i][1];
            if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mp[nx][ny]==1&&vis[nx][ny]==0){
                vis[nx][ny]=t.val+1;
                q.push({nx,ny,t.val+1});
            }
        }
    }
}
int main(){
    cin>>n>>m;
    int stx,sty;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>mp[i][j];
            if(mp[i][j]==2) {
                stx=i;sty=j;
            }
        }
    }
    bfs(stx,sty);
    int k;cin>>k;
    unordered_map<int,int>cnt;
    for(int i=1;i<=k;i++){
        int x,y;cin>>y>>x;
        step[i].val=vis[x][y];
        step[i].id=i;
        cnt[step[i].val]++;
    }
    sort(step+1,step+1+k,cmp);
    for(int i=1;i<=k;i++){
        if(cnt[step[i].val]==1&&step[i].val>0){
            cout<<step[i].id<<' '<<step[i].val;
            return 0;
        }
    }
    cout<<"No winner."<<endl;
}
/*
//错误代码,从每一个终点开始bfs,得18分
#include<iostream>
#include<queue>
#include<algorithm>
#include<unordered_map>
using namespace std;
int n,m;
int k;
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int mp[110][110];
struct node{
    int x,y,val;
};
struct node2{
    int id,val;
}step[1100];
bool cmp(node2 a,node2 b){
    return a.val<b.val;
}
int bfs(int x,int y){
    queue<node>q;
    int vis[110][110]={0};
    q.push({x,y,0});
    while(!q.empty()){
        node t=q.front();
        q.pop();
        if(mp[t.x][t.y]==2) return t.val;
        for(int i=0;i<4;i++){
            int nx=t.x+dir[i][0];
            int ny=t.y+dir[i][1];
            if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mp[nx][ny]!=0&&vis[nx][ny]==0){
                vis[nx][ny]==1;
                q.push({nx,ny,t.val+1});
            }
        }
    }
    return 0;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>mp[i][j];
        }
    }
    cin>>k;
    unordered_map<int,int>cnt;
    for(int i=1;i<=k;i++){
        int x,y;cin>>y>>x;
        step[i].val=bfs(x,y);
        step[i].id=i;
        cnt[step[i].val]++;
    }
    sort(step+1,step+1+k,cmp);
    for(int i=1;i<=k;i++){
        if(cnt[step[i].val]==1&&step[i].val>0){
            cout<<step[i].id<<' '<<step[i].val;
            return 0;
        }
    }
    cout<<"No winner."<<endl;
}
*/

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值