zoukankan      html  css  js  c++  java
  • 洛谷 P1825 [USACO11OPEN]玉米田迷宫Corn Maze

    题目描述

    去年秋天,奶牛们去参观了一个玉米迷宫,迷宫里有一些传送装置,可以将奶牛从一点到另一点进行瞬间转移。这些装置可以双向使用:一头奶牛可以从这个装置的起点立即到此装置的终点,同时也可以从终点出发,到达这个装置的起点。如果一头奶牛处在这个装置的起点或者终点,这头奶牛就必须使用这个装置。

    玉米迷宫的外部完全被玉米田包围,除了唯一的一个出口。

    这个迷宫可以表示为N×M的矩阵(2 ≤ N ≤ 300; 2 ≤ M ≤ 300),矩阵中的每个元素都由以下项目中的一项组成:

    1、 玉米,这些格子是不可以通过的。

    2、 草地,可以简单的通过。

    3、 一个装置的结点,可以将一头奶牛传送到相对应的另一个结点。

    4、出口

    奶牛仅可以在相邻两个格子之间移动,要在这两个格子不是由玉米组成的前提下才可以移动。奶牛能在一格草地上可能存在的四个相邻的格子移动。从草地移动到相邻的一个格子需要花费一个单位的时间,从装置的一个结点到另一个结点需要花费0个单位时间。

    被填充为玉米的格子用“#”表示,草地用“.”表示,每一对装置的结点由相同的大写字母组成“A-Z”,且没有两个不同装置的结点用同一个字母表示,出口用“=”表示。

    Bessie在这个迷宫中迷路了,她知道她在矩阵中的位置,将Bessie所在的那一块草地用“@”表示。求出Bessie需要移动到出口处的最短时间。

    例如以下矩阵,N=5,M=6:

    ###=##
    #.W.##
    #.####
    #.@W##
    ######

    唯一的一个装置的结点用大写字母W表示。

    最优方案为:先向右走到装置的结点,花费一个单位时间,再到装置的另一个结点上,花费0个单位时间,然后再向右走一个,再向上走一个,到达出口处,总共花费了3个单位时间。

    输入输出格式

    输入格式:

     

    第一行:两个用空格隔开的整数N和M;

    第2-N+1行:第i+1行描述了迷宫中的第i行的情况(共有M个字符,每个字符中间没有空格。)

     

    输出格式:

     

    一个整数,表示Bessie到达终点所需的最短时间。

     

    输入输出样例

    输入样例#1: 
    5 6
    ###=##
    #.W.##
    #.####
    #.@W##
    ######
    
    输出样例#1: 
    3
    分析
    走迷宫加强版,每次多了瞬间传送的情况,注意判断细节即可(第一次写的时候竟然以为只有一个传送门W 23333).
    其实我debug了一小时
    wwx你要补偿我,肉偿
    代码
    #include<bits/stdc++.h>
    using namespace std;
    
    char mp[1000][1000];
    int    book[1000][1000];
    int n,m;
    int beginx,beginy;
    
    int move_beginx[30];
    int move_beginy[30];
    int move_endy[30];
    int move_endx[30];
    
    int changex[5]={0,0,1,0,-1};
    int changey[5]={0,1,0,-1,0};
    
    struct Point
    {
        int x;
        int y;
        int step;
        Point(int _x,int _y,int _step):
            x(_x),y(_y),step(_step){}//构造函数 
    };
    
    queue<Point> q;
    int ans;
    int flag[30];
    
    int main()
    {
    //    freopen("testdata.in","r",stdin);
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>mp[i][j];
                if(mp[i][j]=='@')
                {
                    beginx=i;
                    beginy=j;
                }
                if(mp[i][j]>='A'&&mp[i][j]<='Z')
                {
                    if(flag[mp[i][j]-'A']==0)
                    {
                        flag[mp[i][j]-'A']=1;
                        move_beginx[mp[i][j]-'A']=i;
                        move_beginy[mp[i][j]-'A']=j;
                    }
                    else
                    {
                        move_endx[mp[i][j]-'A']=i;
                        move_endy[mp[i][j]-'A']=j;
                    }
                }//存储传送门 
            }
        }
        
        q.push(Point(beginx,beginy,0));
        book[beginx][beginy]=1;//记得起点标记 
        while(!q.empty())
        {
            Point now_node=q.front();
            q.pop();
            int now_x=now_node.x;
            int now_y=now_node.y;
    //        cout<<now_x<<" "<<now_y<<" "<<mp[now_x][now_y]<<endl; 
            int now_step=now_node.step;
                    
            for(int i=1;i<=4;i++)
            {
                int new_x=now_x+changex[i];
                int new_y=now_y+changey[i];
    
                if(new_x>n||new_x<1) continue;
                if(new_y>m||new_y<1) continue;
                if(mp[new_x][new_y]=='#') continue;
                if(book[new_x][new_y]==1) continue;
    
                book[new_x][new_y]=1;
                if(mp[new_x][new_y]=='=')
                {
                    ans=now_step+1;
                    goto u;
                }//搜到答案 
    
                if(mp[new_x][new_y]>='A'&&mp[new_x][new_y]<='Z')//提前打了标记不会存在传来传去的情况 
                {
                    if((new_x==move_beginx[mp[new_x][new_y]-'A'])&&(new_y==move_beginy[mp[new_x][new_y]-'A']))
                    {
                        if(move_endx[mp[new_x][new_y]-'A']==0) continue;
                        int jump_x=move_endx[mp[new_x][new_y]-'A'];
                        int jump_y=move_endy[mp[new_x][new_y]-'A'];
                        q.push(Point(jump_x,jump_y,now_step+1));
                    }//传送门其中一端 
                    else if((new_x==move_endx[mp[new_x][new_y]-'A'])&&(new_y==move_endy[mp[new_x][new_y]-'A']))
                    {
                        if(move_beginx[mp[new_x][new_y]-'A']==0) continue;
                        int jump_x=move_beginx[mp[new_x][new_y]-'A'];
                        int jump_y=move_beginy[mp[new_x][new_y]-'A'];//不知道为什么直接赋值给new_x会挂,新开了个变量 
                        q.push(Point(jump_x,jump_y,now_step+1));
                    }//另一端 
                }//是传送门 
                else
                {
                    q.push(Point(new_x,new_y,now_step+1));
                }//不是传送门 
            }
        }
        u:cout<<ans<<endl;
        return 0;
    }
    
    
    



  • 相关阅读:
    真香!PySpark整合Apache Hudi实战
    Apache Hudi又双叕被国内顶级云服务提供商集成了!
    Apache Hudi集成Apache Zeppelin实战
    实战 | 将Apache Hudi数据集写入阿里云OSS
    实战|使用Spark Structured Streaming写入Hudi
    Apache Hudi 设计与架构最强解读
    【Flink】Flink作业调度流程分析
    【Flink】深入理解Flink-On-Yarn模式
    【Flink】Flink 底层RPC框架分析
    【MyBatis】MyBatis自动生成代码之查询爬坑记
  • 原文地址:https://www.cnblogs.com/KyleDeng/p/9902228.html
Copyright © 2011-2022 走看看