LeeCode 1728 任意图上博弈

题意

传送门 LeeCode 1728 猫和老鼠 II

题解

任意图上博弈,可参考 Games on arbitrary graphs。具体而言,将博弈双方位置加之先后手状态看作任意图上的一个节点,并根据状态转移建立反图。对于可以确定胜负态的节点,以其为起点,使用类似拓扑序更新的操作不断递推其余节点的状态。对于 n × m n\times m n×m的方格,任意图博弈求解时间复杂度为 O ( ( n m ) 2 max ⁡ ( n , m ) ) O\Big((nm)^{2}\max(n,m)\Big) O((nm)2max(n,m))

#include <bits/stdc++.h>
using namespace std;

class Solution {
   public:
    bool canMouseWin(vector<string>& grid, int catJump, int mouseJump) {
        int n = grid.size(), m = grid[0].size();
        int mx = -1, my = -1;
        int cx = -1, cy = -1;
        int fx = -1, fy = -1;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                auto c = grid[i][j];
                if (c == 'M') {
                    mx = i, my = j;
                }
                if (c == 'C') {
                    cx = i, cy = j;
                }
                if (c == 'F') {
                    fx = i, fy = j;
                }
            }
        }
        const vector<int> dx = {0, 0, -1, 1};
        const vector<int> dy = {-1, 1, 0, 0};
        int pos_num = n * m;
        int state_num = pos_num * pos_num * 2;
        vector<vector<int>> g(state_num);
        auto get = [&](int u, int v, int who) {
            return u + v * pos_num + who * pos_num * pos_num;
        };
        auto judge = [&](int x, int y) {
            return 0 <= x && x < n && 0 <= y && y < m && grid[x][y] != '#';
        };
        auto ed = [&](int cv, int mv) {
            int fv = fx * m + fy;
            return cv == mv || cv == fv || mv == fv;
        };
        for (int cv = 0; cv < pos_num; ++cv) {
            for (int mv = 0; mv < pos_num; ++mv) {
                if (ed(cv, mv)) {
                    continue;
                }
                for (int who = 0; who < 2; ++who) {
                    int w = who == 0 ? cv : mv;
                    int sx = w / m, sy = w % m;
                    int lim = who == 0 ? catJump : mouseJump;
                    for (int k = 0; k < (int)dx.size(); ++k) {
                        int x = sx, y = sy;
                        for (int d = 0; d <= lim; ++d) {
                            if (!judge(x, y)) {
                                break;
                            }
                            if (who == 0) {
                                g[get(x * m + y, mv, who ^ 1)].push_back(get(cv, mv, who));
                            } else {
                                g[get(cv, x * m + y, who ^ 1)].push_back(get(cv, mv, who));
                            }
                            x += dx[k];
                            y += dy[k];
                        }
                    }
                }
            }
        }
        vector<int> indeg(state_num);
        for (int u = 0; u < state_num; ++u) {
            for (int v : g[u]) {
                indeg[v] += 1;
            }
        }
        vector<int> win(state_num, -1);
        function<void(int)> dfs = [&](int v) {
            for (int u : g[v]) {
                if (win[u] == -1) {
                    if (win[v] == 0) {
                        win[u] = 1;
                    } else {
                        indeg[u] -= 1;
                        if (indeg[u] == 0) {
                            win[u] = 0;
                        }
                    }
                    if (win[u] != -1) {
                        dfs(u);
                    }
                }
            }
        };
        for (int cv = 0; cv < pos_num; ++cv) {
            int x = cv / m, y = cv % m;
            if (judge(x, y)) {
                for (int who = 0; who < 2; ++who) {
                    int v = get(cv, cv, who);
                    win[v] = who ^ 1;
                    dfs(v);
                }
            }
        }
        for (int v = 0; v < pos_num; ++v) {
            int x = v / m, y = v % m;
            int f = fx * m + fy;
            if (judge(x, y) && v != f) {
                int u = get(f, v, 1);
                win[u] = 0;
                dfs(u);
                int w = get(v, f, 0);
                win[w] = 0;
                dfs(w);
            }
        }
        int res = win[get(cx * m + cy, mx * m + my, 1)];
        return res == 1;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/585687.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker容器添加修改端口映射的方法与详细步骤

1、先找到要修改的容器hash值&#xff1a; 2、然后退出docker Desktop服务 &#xff08;因为在线状态配置文件修改保存不了&#xff09; 3、资源管理器中打开最新安装的Docker的配置文件的路径&#xff1a; 4、打开后修改其中的 config.v2.json 和 hostconfig.json 5、启动…

【C++】哈希表的底层逻辑

目录 一、哈希概念 1、哈希冲突 2、哈希冲突的解决 a、闭散列 &#x1f7e2;插入 &#x1f7e2;查找 &#x1f7e2;删除 &#x1f7e2;其他类型的数据 &#x1f7e2;实现 b、 开散列 &#x1f7e2;插入 &#x1f7e2;查找 &#x1f7e2;删除 &#x1f7e2;析构 &a…

《霍格沃茨之遗》找不到emp.dll如何修复?分享5种亲测有效的方法

在我们享受电脑游戏带来的乐趣时&#xff0c;偶尔会遇到一些技术上问题&#xff0c;具体来说&#xff0c;当你启动一款游戏&#xff0c;系统却弹出一个提示“由于找不到emp.dll文件&#xff0c;因此无法继续执行代码”&#xff0c;这样的情况确实让人感到扫兴。这究竟是什么原因…

.net core ef 连表查询

Information和TypeInfo连表查询 类似&#xff1a; select st.Title1,si.* from [Star_Information] si left join Star_TypeInfo st on si.typeId2st.id 先在EfCoreDbContext.cs配置 protected override void OnModelCreating(ModelBuilder builder){base.OnModelCreating(b…

Jupyter Notebook 中使用虚拟环境的Python解释器

问题&#xff1a;创建虚拟环境&#xff0c;在pycharm中配置虚拟环境的Python解释器&#xff0c;然后在pycharm中打开ipynb&#xff0c;执行发现缺少包&#xff0c;但是虚拟环境中已经安装了 解决方式&#xff1a; 配置Jupyter Notebook 使用虚拟环境的Python解释器 1&#x…

ElasticSearch总结2

一、创建索引库&#xff1a;PUT ES中通过Restful请求操作索引库、文档。请求内容用DSL语句来表示。创建索引库和mapping的DSL语法如下&#xff1a; 整个jason 里边&#xff0c;它有一个叫mapping的属性&#xff0c;代表的是映射。映射里边有properties代表就是字段。可以看到这…

C++入门系列-缺省参数

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 缺省参数的概念 缺省参数是生命或者定义函数时为函数的参数指定一个缺省值&#xff0c;在调用该函数时&#xff0c;如果没有指定实参则采用该形参的缺省值&#xff0c;否则使用…

一单利润100+,不起眼的小生意,却能闷声发财!

今天&#xff0c;我想向大家介绍一个看似不太热门&#xff0c;但实际上需求很高的项目——酒店代订。这个项目其实很早以前就已经有人开始尝试了&#xff0c;但可能并没有被大众所熟知。简而言之&#xff0c;酒店代订就是帮助他人通过我们来预订他们想要入住的酒店。 当客户将…

ThinkPHP5 SQL注入漏洞敏感信息泄露漏洞

1 漏洞介绍 ThinkPHP是在中国使用极为广泛的PHP开发框架。在其版本5.0&#xff08;<5.1.23&#xff09;中,开启debug模式&#xff0c;传入的某参数在绑定编译指令的时候又没有安全处理&#xff0c;预编译的时候导致SQL异常报错。然而thinkphp5默认开启debug模式&#xff0c…

Allegro如何将铜皮复制到其他层

如何将铜皮复制到其他层 方法一&#xff1a; 第一步&#xff1a;选择需要复制的铜皮&#xff0c;然后按下CtrlC 第二步&#xff1a;选择要粘贴到的层面&#xff0c;然后按Ctrl V 将在所在层面创建一个新的铜皮&#xff0c;几何形状与原铜皮完全一样 方法二&#xff1a; 第一…

基于SSM的个人博客系统(二)

目录 第四章 系统设计 4.1 系统总流程 4.2 博主用例 4.3 游客用例 4.4 系统类 一、博客类 二、博客类型类 三&#xff0c;评论类&#xff1a; 四&#xff0e;友情链接类 4.5 E-R图 4.6 系统表设计 前面内容请移步 基于SSM的个人博客系统&#xff08;一&#xff09;…

docker mysql更新升级版本

一、环境说明 操作系统&#xff1a;Centos7 数据库版本&#xff1a;MySql 8.0.22 数据库中数据量不大&#xff0c;处于开发/测试环境&#xff0c;风险较低 二、升级原因 升级是因为测评漏洞&#xff0c;在进行国家三级等级保护测评过程中&#xff0c;漏扫发现多个MySql漏洞…

(十五)Servlet教程——Servlet文件上传

JSP和HTML标签一起使用&#xff0c;来允许用户把文件上传到服务器。 首先我们需要创建一个前端界面&#xff0c;创建上传文件表单时&#xff0c;需要注意以下几点&#xff1a; (1) 表单的method属性必须设置为POST方法&#xff0c; 不能使用GET方法。 (2) 表单enctype属性应该…

【Unity面试篇】Unity 面试题总结甄选 |Unity基础篇 | ❤️持续更新❤️

2.2 前言 关于Unity面试题相关的所有知识点&#xff1a;&#x1f431;‍&#x1f3cd;2023年Unity面试题大全&#xff0c;共十万字面试题总结【收藏一篇足够面试&#xff0c;持续更新】为了方便大家可以重点复习某个模块&#xff0c;所以将各方面的知识点进行了拆分并更新整理…

19 做好微服务间依赖的治理和分布式事务

在前两讲里&#xff0c;分别从微服务的对外接口、消息消费以及微服务自身的相关编码规范上阐述了“防备上游、做好自己”这两个准则如何落地。 在本讲里&#xff0c;将会讲解为什么要“怀疑下游”&#xff0c;以及有哪些手段可以落地此条准则。此外&#xff0c;还会介绍在进行…

基于SSM的个人博客系统(三)

目录 第五章 系统实现 5.1 登录模块 5.1.1 博主登录 5.2 博客管理模块&#xff1a; 5.2.1 博客查询 5.2.2 博客新建 5.2.3 博客修改 5.2.4 博客删除 5.3 博客类别管理模块 前面内容请移步 基于SSM的个人博客系统&#xff08;二&#xff09; 个人博客系统的设计…

Qt+Ubuntu20.04:打包qt

打包程序 参考 qt项目在Linux平台上面发布成可执行程序.run_qt.run不是虚拟机的配置文件-CSDN博客 Linux下Qt程序的打包发布(1)-不使用第三方工具 - 知乎 (zhihu.com) 过程 1、Release编译 先将你的程序在release下编译通过&#xff0c;保证下面打包的程序是你最新的。 2…

沐风老师3DMAX一键生成桌子插件TableMaker使用方法

3DMAX一键生成桌子插件TableMaker使用教程 3DMAX一键生成桌子插件TableMaker&#xff0c;参数化方式快速创建各种样式桌子模型。 【适用版本】 3dMax2011-2025&#xff08;不仅限于此范围&#xff09; 【安装方法】 3DMAX一键生成桌子插件无需安装&#xff0c;使用时直接拖动…

GCB | 陆地生态系统C:N:P化学计量对降水变化的响应

西北农林科技大学水保学院上官周平研究员团队在陆地生态系统C:N:P化学计量对降水变化的响应方面取得新进展&#xff0c;并以“C:N:P stoichiometry of plants, soils, and microorganisms: Response to altered precipitation”为题发表在国际生态环境领域著名期刊Global Chang…

SpringBoot之自定义注解参数校验

SpringBoot之自定义注解参数校验 为什么要自定义注解 我这里先引入一个例子&#xff0c;就比如我现在要写文章&#xff0c;文章也许写完正要发布&#xff0c;也可以是还没写完正要存草稿&#xff0c;前端往后端发送数据&#xff0c;如果前端的state不是草稿或者已发布状态&…
最新文章