1 solutions

  • 0
    @ 2025-3-3 16:21:27

    C :

    #include <stdio.h>
    #include <stdlib.h>
    
    struct point
    {
        int x;//行坐标
        int y;//列坐标
        int hp;//
        int step;//从出发点到达该点的步数
    }queue[82];
    
    int map[9][12];//map地图
    int n,m,min_step,sign=0;//地图有n行m列
    int location[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//4个方位
    int recnt_step[9][9],recnt_hp[9][9];
    //recnt_hp用于记录最近经过该格时小H的最优血量
    //recnt_step用于记录最近经过该格时小H的最优步数
    
    int check(int x,int y)//检查
    {
        if(x>=0&&x<n&&y>=0&&y<m&&map[x][y])//坐标合法且该格不为障碍
        {
            return 1;
        }
        return 0;
    }
    
    int BFS(int home_x,int home_y)
    {
        int i,x,y;
        int head=0,tail=0;//定义队首、队尾
        //从队尾入队
        queue[tail].x=home_x;
        queue[tail].y=home_y;
        queue[tail].hp=6;//刚开始血量为6
        tail++;
        while(head<tail&&!sign)//在队列未空时
        {
            if(queue[head].hp>1)//当血量大于1
            {
                for(i=0;i<4&&!sign;i++)//尝试遍历四个方向
                {
                	//计算坐标
                    x=queue[head].x+location[i][0];
                    y=queue[head].y+location[i][1];
                    if(!check(x,y))//若坐标不合格
                    {
                        continue;//直接遍历下一个方向
                    }
                    if(recnt_hp[x][y]>=queue[head].hp-1&&recnt_step[x][y]<=queue[head].step+1)//若小H走到该格时,血量不高于前一次并且步数不低于前一次,则说明小H此时的路线一定不是最优解
                    {
                        continue;
                    }
                    else
                    {
                        //新点从队尾入队
                        queue[tail].x=x;
                        queue[tail].y=y;
                        //更新各项指标
                        queue[tail].step=queue[head].step+1;//从队长到达相邻的格子需要多走1步
                        queue[tail].hp=map[x][y]==4? 6:queue[head].hp-1;//从队长到达相邻的格子需要多消耗1点血
                        recnt_hp[x][y]=queue[tail].hp;//更新最优血量
                        recnt_step[x][y]=queue[tail].step;
                        if(map[x][y]==3)//若找到家
                        {
                            sign=1;
                            min_step=queue[tail].step;//记录最小步数
                        }
                        tail++;
                    }
                }
            }
            head++;//将队员全部入队的旧队长出队
        }
        return 0;
    }
    
    int main()
    {
        int i,j;
        int home_x,home_y;
        //输入数据并搜索出发位置
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                scanf("%d",&map[i][j]);
                if(map[i][j]==2)//找到出发位置
                {
                    home_x=i;
                    home_y=j;
                }
            }
        }
        //广搜
        BFS(home_x,home_y);
        //输出结果
        if(sign)//若找到家
        {
            printf("%d",min_step);
        }
        else
        {
            printf("-1");
        }
        return 0;
    }
    
    
    

    C++ :

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    using namespace std;
    int jz[20][20]={0};//存储原地图
    struct NODE//一个节点,即一个状态
    {
        int x,y,bs,xl;//位置,步数与血量
    }qc,fr;
    int zl[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//增量,即向四周可能走的位置
    int visit[20][20]={0};//visit int版数组
    queue<NODE>wz;//bfs队列
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        int sx,sy;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&jz[i][j]);
            if(jz[i][j]==2)sx=i,sy=j;//记录出发位置
        }
        wz.push((NODE){sx,sy,0,6});//推入队列,这里用了强制类型转换
        visit[sx][sy]=6;//初始位置设置其visit值
        bool tf=true;//判断是否完成任务,tf==false即完成
        while(!wz.empty()&&tf)//直到完全失败或成功
        {
            qc=wz.front();//取队列最前面的节点
            wz.pop();//弹出队列
            if(qc.xl==1)continue;//如果血量为1,则继续
            for(int i=0;i<4&&tf;i++)//四个方向
            {
                if(jz[qc.x+zl[i][0]][qc.y+zl[i][1]])//如果可以到达
                if(visit[qc.x+zl[i][0]][qc.y+zl[i][1]]<qc.xl-1)//如果血量更大
                {
                    fr.x=qc.x+zl[i][0];
                    fr.y=qc.y+zl[i][1];
                    fr.bs=qc.bs+1;//更新新的节点
                    fr.xl=jz[fr.x][fr.y]==4?6:qc.xl-1;//如果下一个节点是有鼠标的,那么有变成6
                    visit[fr.x][fr.y]=qc.xl-1;//更新visit
                    if(jz[fr.x][fr.y]==3)tf=false;//如果任务完成,那么tf更新
                    wz.push(fr);//加入队列
                }
            }
        }
        if(tf)printf("-1");//如果任务失败
        else printf("%d",fr.bs);//如果任务成功,则输出结果
        return 0;
    }
    
    • 1

    Information

    ID
    9956
    Time
    1000ms
    Memory
    128MiB
    Difficulty
    (None)
    Tags
    # Submissions
    0
    Accepted
    0
    Uploaded By