• P4944


    题面

    Time:23 ms,Memory:756.00 KB,Code:3.07KB

    不加 O2,发此篇题解的时候是最优解 rk1。

    题意

    给出一个地图,地图上初始有 (c) 条贪吃蛇和一些食物。

    接下来会给出 (k) 秒内每条贪吃蛇的移动规则,你需要输出 (k) 秒后所有蛇的信息。

    分析&代码

    写一个 Snake 类,来存放所有有关蛇的操作。

    struct node {  //结点
        int x, y;
    };
    
    class Snake {
       private:
        std::deque<node> body;  //蛇
    
        void die(void) { //清除蛇身
            live = false; 
            len = 0;
            while (!body.empty()) {
                node cac = body.front();
                body.pop_front();
                map[cac.x][cac.y] = '&', restFood++;
            }
            return;
        }
    
       public:
        Snake(int x, int y, int id) {  //BFS 寻找蛇身
            this->id = id;
            len = 0;
            live = true;
            static std::queue<node> que;
            que.push((node){x, y});
            while (!que.empty()) {
                node cac = que.front();
                vis[cac.x][cac.y] = true;
                body.push_back(cac), len++;
                que.pop();
                for (int i = 0; i < 4; i++) {
                    int tx = cac.x + way[0][i], ty = cac.y + way[1][i];
                    if (tx >= 1 && tx <= n && ty >= 1 && ty <= m &&
                        !vis[tx][ty] && map[tx][ty] == '#') que.push((node){tx, ty});
                }
            }
            return;
        }
        ~Snake(void) {
            body.clear();
            return;
        }
    
        bool live;
        int id, len;
    
        void move(char way) {
            node to = body.front();
            map[to.x][to.y] = '#';   //删除蛇头
            if (way == 'W') to.x--;  //四个方向
            if (way == 'S') to.x++;
            if (way == 'A') to.y--;
            if (way == 'D') to.y++;
            if (to.x < 1 || to.x > n || to.y < 1 || to.y > m ||
                map[to.x][to.y] == '#' || map[to.x][to.y] == '@') return die();  //如果撞到蛇身或者边界
            body.push_front(to), len++;
            if (map[to.x][to.y] == '&') return restFood--, void(map[to.x][to.y] = '@');  //吃食物
            map[to.x][to.y] = '@';
            map[body.back().x][body.back().y] = '.';  //删除尾部,增加新的头部
            return len--, body.pop_back();
        }
    
        inline bool operator<(const Snake& oth) const {
            return this->len > oth.len || this->len == oth.len && this->id < oth.id;
        }
    };
    

    其中构造函数负责 BFS 初始化蛇身,move(char) 函数负责让蛇向指定方向移动。此时如果蛇死了会直接调用 die(void) 清除蛇身。

    这里有一点巧的就是在蛇吃掉食物后,只要让食物变成新蛇头就可以了。

    如果蛇没有吃掉食物,删除蛇尾并且在前方标记新头即可。


    上面的类定义完之后,面向对象模拟题意即可。

    int main() {
        std::ios::sync_with_stdio(false);
        int k, c;
        std::cin >> n >> m >> k;
        restFood = 0;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) {
                std::cin >> map[i][j];
                if (map[i][j] == '&') restFood++;
            }
        c = 0;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                if (map[i][j] == '@') snakes.push_back((Snake){i, j, ++c});  //通过蛇头直接初始化蛇身
        for (int i = 0; i < c; i++)
            for (int j = 1; j <= k; j++)
                std::cin >> cmd[i][j];
        for (int tim = 1; tim <= k; tim++)
            for (int p = 0; p < c; p++) {
                if (!snakes[p].live) continue;
                snakes[p].move(cmd[p][tim]);  //让蛇向指定方向移动一格
            }
        std::sort(snakes.begin(), snakes.end());
        for (std::vector<Snake>::iterator i = snakes.begin(); i != snakes.end(); i++)
            std::cout << i->len << ' ' << i->id << std::endl;
        std::cout << restFood << std::endl;
        return 0;
    }
    

    完整代码

  • 相关阅读:
    fscanf_s与scanf_s的宽度参数与缓冲区参数分析
    C语言小程序——推箱子(窄字符和宽字符)
    setlocale()函数详解——C语言
    在源文件(.c)和头文件(.h)中声明和定义的区别——C语言
    枚举类型enum详解——C语言
    宽字符————_T、_TEXT、L、TEXT之间的区别
    宽字符wchar_t和窄字符char——putwchar、wprintf
    extern的使用详解(多文件编程)——C语言
    编程的时候命名词穷了怎么办
    [C#/UI] 使用 await 实现业务对 UI 的控制反转
  • 原文地址:https://www.cnblogs.com/macesuted/p/solution-P4944.html
Copyright © 2020-2023  润新知