• UVALive 2035 The Monocycle(BFS状态处理+优先队列)


      这道题目真是非常坎坷啊,WA了很多次,但所有的思路都是奔着广搜去想的,一开始出现了比答案大的数据,才想到了应该是优先队列,再说加上也肯定不会错。一开始我读错了题意,以为旋转并且前行需要的时间跟其他一样,但是旋转的动作是需要额外计时的。我的第一种方法错误原因还没有找到,我在旋转以后就直接改动了位置,感觉没有什么本质区别,旋转了以后,肯定要走啊,我直接加上时间也没什么问题,我也把所能想到的测试用例都试过了,与AC代码完全一致,真是搞不懂,这要是CF就好了。于是,学习了别人的代码,改了改我原先的地方,发现还真是那里错了。。又经过了一番钻研,才算优雅的AC了题目。

      吐槽就到这里了,我来说一下代码吧。

      状态使用四维数组保存,位置占两维,方向和颜色各占一维,颜色就是题目中给的5种颜色,方向最好给定一个标号,便于以后的行走。(0N ,1E, 2S,3W) ,在搜索过程中,每一次操作都将会耗费1秒种,操作分为向左右旋转,即改变dir,向目前的方向移动,改变x和y。 每次都让这3中新的状态进入优先队列,选择耗费时间小的作为队头,这样当搜索到的时候,便是耗费最小的步数。

    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<queue>
    #include<cstring>
    using namespace std;
    #define maxn 30
    struct Node{
        int x,y,col,dir,tim;
        bool operator < (Node a)const{
            return a.tim < tim;
        }
    };
    char maps[maxn][maxn];
    int state[maxn][maxn][10][10],n,m,go[4][2]={{-1,0},{0,1},{1,0},{0,-1}};///注意按照自己规定的方向处理数组,便于行走
    priority_queue<Node> que;
    bool ok(Node a){
        if(a.x>=0&&a.x<n && a.y>=0&&a.y<m && state[a.x][a.y][a.col][a.dir]==0 && maps[a.x][a.y]!='#') return true;
        return false;
    }
    void mark(Node a){
        state[a.x][a.y][a.col][a.dir] = 1;
    }
    int BFS(Node s){
        while(!que.empty()) que.pop();
        que.push(s);
        state[s.x][s.y][s.col][s.dir] = 1;
        while(!que.empty()){
            Node now = que.top();
            que.pop();
            if(maps[now.x][now.y]== 'T' && now.col==0) return now.tim;
            Node nxt = now;
            nxt.tim++;///每一次操作,耗费1s
            nxt.dir = (now.dir + 1)%4;
            if(ok(nxt)){que.push(nxt); mark(nxt);}
            ///第一种向右转,注意是转
    
            nxt.dir = now.dir - 1; if(nxt.dir<0) nxt.dir=3;
            if(ok(nxt)){que.push(nxt); mark(nxt);}
            ///第二种向左转
    
            nxt.dir = now.dir;
            nxt.col=(now.col+1)%5;
            nxt.x = go[now.dir][0] + now.x;
            nxt.y = go[now.dir][1] + now.y;
            ///向所在方向行走,并且改变颜色
            if(ok(nxt)) {que.push(nxt); mark(nxt);}
        }
        return -1;
    }
    int main()
    {
        int ca = 0;
        while(EOF != scanf("%d%d",&n,&m)){
            if(n==0&& m==0) break;
            if(ca) printf("
    "); ///注意不要多输出空行
            for(int i = 0;i < n;i++)
                scanf("%s",maps[i]);
            Node start;
            memset(state,0,sizeof(state));
            for(int i = 0;i < n;i++){
                for(int j = 0;j < m;j++){
                    if(maps[i][j]=='S'){
                        start.x = i; start.y = j;
                        start.col=0;  start.dir=0;
                        start.tim = 0;
                    }
                }
            }
            int ans = BFS(start);
            printf("Case #%d
    ",++ca);
            if(ans == -1) printf("destination not reachable
    ");
            else printf("minimum time = %d sec
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    第3次实践作业
    第2次实践作业
    第1次实践作业
    2019 SDN大作业
    第05组 Beta版本演示
    个人作业——软件工程实践总结&个人技术博客
    个人作业——软件评测
    Springboot项目部署到云服务器(Ubuntu 18.04)
    结对第二次作业——某次疫情统计可视化的实现
    结对第一次—疫情统计可视化(原型设计)
  • 原文地址:https://www.cnblogs.com/jifahu/p/5685519.html
Copyright © 2020-2023  润新知