【QED】爱丽丝与混沌的无尽海
文章目录
- 题目
- 题目描述
- 输入输出格式
- 数据范围
- 测试样例
- 思路
- 代码
- 复杂度分析
- 时间复杂度
- 空间复杂度
题目
题目链接🔗
题目描述
如图所示,爱丽丝在一个3x3的迷宫之中,每个方格中标有 1 − 9 1-9 1−9各不相同的数字,爱丽丝可以从一格出发,到达任意相邻的格子。每到达一个格子,爱丽丝便获得了该格子上的数字,假设爱丽丝以 1 → 3 → 5 1\to3\to5 1→3→5 的顺序走过格子,她就获得了 135
,长度为3的字符串。爱丽丝可能从任意一格出发,请你计算长度为 n n n 的字符串一共有多少种可能性。答案可能很大,最终答案请对 998244353 998244353 998244353 取模。
注:不完全相同的两个字符串为两种不同的可能性,如 135
和 139
,135
和 131
。
同一格子可以重复走过。
输入输出格式
【输入格式】
共 4 4 4 行
第 1 1 1行到第 3 3 3行,每行 3 3 3个用空格分隔开的数字 a i j ( 1 ≤ a i j ≤ 9 ) a_{ij} (1 \le a_{ij} \le 9) aij(1≤aij≤9),代表第 i i i行第 j j j列格子上的数字。
第 4 4 4行输入一个数字 n n n,表示字符串的长度。
【输出格式】
共 1 1 1 行
输出长度为 n n n 的字符串的所有可能性对 998244353 998244353 998244353 的模数。
数据范围
1 ≤ a i j ≤ 9 1 \le a_{ij} \le 9 1≤aij≤9
1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1≤n≤105
测试样例
input1:
1 2 3
4 5 6
7 8 9
2
output1:
24
input2:
3 2 1
9 8 7
4 5 6
100000
output2:
528035646
思路
题目给定了9个数字之间相互不一样,则具体是什么数字已经不重要了,题目化简为:具体来说,给定一个 3x3 的迷宫,每个格子都可以作为起点,爱丽丝可以从一个格子出发,按照某种规则在相邻格子中移动,经过 n 步后最终到达其他格子。计算所有这样的路径的数量,并输出结果。
我们可以用一个三维数组,用来存储从某个位置 (x, y) 出发,经过 n 步后可以到达的路径数量。结果需要对这个质数取模。
计算的过程中可以使用深度优先搜索递归计算从迷宫中的某个格子出发,经过 n 步后能到达的所有路径的数量,由于数据量较大,可以采用记忆化搜索来避免重复计算,从而提高效率。
递归思路如下:
- 递归定义:
函数 dfs(x, y, n) 计算从 (x, y) 这个位置出发,经过 n 步可以达到的所有可能路径的数量。- 递归边界条件:
当 n == 1 时,表示路径的长度为 1,起点本身就是一个有效路径。因此,dfs(x, y, 1) 直接返回 1,表示当前位置的路径数量为 1。- 递归转移:
对于每个 (x, y) 格子,函数会检查该格子周围的 8 个相邻格子(上下左右以及四个对角线方向的格子)。对于每一个相邻格子 (i, j),如果它与当前位置 (x, y) 相邻,即 abs(i-x) + abs(j-y) == 1,那么递归地调用 dfs(i, j, n-1) 来计算从该相邻格子出发,经过 n-1 步能到达的路径数量。
然后将所有这些相邻格子的结果加起来,得到当前位置 (x, y) 出发,经过 n 步的路径总数。- 记忆化搜索:
mem[x][y][n] 用来记录已经计算过的结果,避免重复计算。如果 mem[x][y][n] 不为 0,表示该状态已经计算过,直接返回该结果。这大大提高了效率,因为同一个状态(从某个位置出发,经过相同步数)不会被重复计算。- 递归的返回值:
每次递归的结果是将相邻格子通过递归计算得到的路径数量进行累加,并对 998244353 取模,以确保结果不会超过整数范围。
代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using ld=long double;
constexpr int p=998244353;ll mem[5][5][100005];
ll dfs(int x, int y, int n)
{if(mem[x][y][n]!=0)return mem[x][y][n];if(n==1)return mem[x][y][n]=1;ll res=0;for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)if(abs(i-x)+abs(j-y)==1)res = (res + dfs(i, j, n-1)) % p;return mem[x][y][n] = res;
}int main()
{int n;for(int i=0;i<=9;i++)cin>>n;ll ans=0;for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)ans=(ans+dfs(i,j,n))%p;cout<<ans;return 0;
}
复杂度分析
时间复杂度
-
递归调用:
递归函数 d f s ( x , y , n ) dfs(x, y, n) dfs(x,y,n) 的目的是计算从位置 ( x , y ) (x, y) (x,y) 出发,经过 n n n 步能够到达的所有路径数量。对于每个位置 ( x , y ) (x, y) (x,y),递归需要访问它的相邻格子(最多有 4 4 4 个相邻格子),并进行递归调用。
因此,每次递归都会对最多 4 4 4 个相邻格子进行递归调用。 -
记忆化搜索:
通过记忆化数组 m e m [ x ] [ y ] [ n ] mem[x][y][n] mem[x][y][n] 来避免重复计算,如果某个 ( x , y , n ) (x, y, n) (x,y,n) 状态已经计算过,直接返回已存储的结果。这意味着每个状态只会计算一次,从而避免了指数级的重复计算。 -
递归的状态数:
递归的状态由 $(x, y) $和 n n n 决定。由于迷宫的大小是固定的 ( 3 ∗ 3 ) (3*3) (3∗3),因此有 9 个可能的 ( x , y ) (x, y) (x,y) 位置。
对于每个位置, n n n 可以从 1 1 1 到给定的最大步数 n n n 进行递归。因此,递归的状态数为:
状态数 = 9 × n 状态数=9×n 状态数=9×n其中, 9 9 9 是 ( x , y ) (x, y) (x,y) 的取值范围, n n n 是步数的最大值。 -
每次递归的工作量:
每次递归需要遍历最多 4 4 4 个相邻格子,并对每个相邻格子进行递归调用。这部分的计算量是常数级别的 O ( 1 ) O(1) O(1)。
综上,时间复杂度可以表示为:
时间复杂度 = O ( 9 × n 4 ) = O ( 36 n ) 时间复杂度=O(9×n4)=O(36n) 时间复杂度=O(9×n4)=O(36n)
由于常数项 36 36 36 可以忽略不计,最终的时间复杂度为:
O ( n ) O(n) O(n)
空间复杂度
- 记忆化数组:
记忆化数组 m e m [ x ] [ y ] [ n ] mem[x][y][n] mem[x][y][n] 用于存储每个位置 ( x , y ) (x, y) (x,y) 和步数 n n n 的计算结果。因为 ( x , y ) (x, y) (x,y) 的位置有 9 9 9 个,而步数 n n n 最大为给定的 n n n,所以数组的大小为:
m e m 数组的大小 = 9 × n mem 数组的大小=9×n mem数组的大小=9×n - 递归栈空间:
递归的最大深度为 n n n(因为递归每次调用时,步数 n n n 减 1 1 1)。因此,递归栈的空间复杂度为 O ( n ) O(n) O(n)。
综上,空间复杂度为:
空间复杂度 = O ( 9 × n + n ) = O ( n ) 空间复杂度=O(9×n+n)=O(n) 空间复杂度=O(9×n+n)=O(n)
相关文章:

【QED】爱丽丝与混沌的无尽海
文章目录 题目题目描述输入输出格式数据范围测试样例 思路代码复杂度分析时间复杂度空间复杂度 题目 题目链接🔗 题目描述 如图所示,爱丽丝在一个3x3的迷宫之中,每个方格中标有 1 − 9 1-9 1−9各不相同的数字,爱丽丝可以从一格…...
IO模型学习
背景知识 Socket 套接字。 客户端和服务端通信时,客户端需要数据出口,服务端需要数据入口,这两个出入口就是Socket。数据接收方新建socket后需要绑定ip和端口号,这样客户端才能链接上socket。连接的过程就是 三次握手 FD file …...

Doxygen 使用指南
Doxygen 是一个文档生成工具,可以从源代码中的注释生成高质量的文档,支持多种编程语言(如 C/C、Python、Java 等)。以下是 Doxygen 的基本使用方法。 1. 安装 Doxygen 1.1 下载 Doxygen 访问 Doxygen 官网。根据操作系统选择合适…...

设计模式与游戏完美开发(2)
更多内容可以浏览本人博客:https://azureblog.cn/ 😊 该文章主主题内容均来自《设计模式与游戏完美开发》—蔡升达 第二篇 基础系统 第四章 游戏主要类——外观模式(Facade) 一、游戏子功能的整合 一个游戏程序常常由内部数个不…...
Coroutine 基础三 —— 结构化并发(二)
1、协程的结构化异常管理 如果一个协程抛异常,它所在的整个协程树上的其他协程(向上是父协程到根协程,向下是所有后代协程)都会被取消。因此协程发生异常的后果是十分严重的。 先讲原理,再说解决方案。 协程异常的处…...

GXUOJ-算法-第一次作业
1.整数划分 问题描述 GXUOJ | 整数划分 题解 #include<bits/stdc.h> using namespace std; const int N1010,mod1e97;int n; int f[N];int main(){cin>>n;f[0]1;for(int i1;i<n;i){for(int ji;j<n;j){f[j](f[j]f[j-i])%mod;}}cout<<f[n]; } 2.汉诺塔…...

Springboot项目Druid运行时动态连接多数据源的功能
项目支持多数据库连接是个很常见的需求,这不仅是要在编译前连已经知道的多个数据库,有时还要在程序运行时连后期增加的多个数据源来获得数据。 一、编译前注册数据库连接 1.引入依赖包 <!-- springboot 3.x --><dependency><groupId&g…...
字符串匹配——KMP算法
前言 刷到字符串匹配的力扣题了【28. 实现 strStr() 】,这题简单吧用库函数做就可以,说难吧,就得引出大名鼎鼎的线性匹配算法——KMP。 目录 KMP 算法背景与原理算法优势 前缀表1. 构建Next数组2. 搜索匹配 KMP 算法背景与原理 KMP&#x…...

Qt开发技术【下拉复选框 MultiSelectComboBox 自定义全选项】
继承ComboBox完成下拉复选框 自定义全选项 效果图 整个控件继承于QCombobox类。主要修改QLineEdit、QListWidget这两部分,QComboBox提供如下接口,可以将这两部分设置为新建的QLineEdit、QListWidget对象 CMultiSelectComboBox::CMultiSelectComboBo…...

20_HTML5 SSE --[HTML5 API 学习之旅]
HTML5 Server-Sent Events (SSE) 是一种技术,它允许服务器向浏览器推送更新。与传统的轮询不同,SSE提供了真正的单向实时通信通道:服务器可以主动发送数据到客户端,而不需要客户端发起请求。这对于实现实时更新的应用非常有用&…...

jetson Orin nx + yolov8 TensorRT 加速量化 环境配置
参考【Jetson】Jetson Orin NX纯系统配置环境-CSDN博客 一 系统环境配置: 1.更换源: sudo vi /etc/apt/sources.list.d/nvidia-l4t-apt-source.list2.更新源: sudo apt upgradesudo apt updatesudo apt dist-upgrade sudo apt-get updat…...

Android Studio IDE环境配置
需要安装哪些东西: Java jdk Java Downloads | OracleAndroid Studio 下载 Android Studio 和应用工具 - Android 开发者 | Android DevelopersAndroid Sdk 现在的Android Studio版本安装时会自动安装,需要注意下安装的路径Android Studio插件…...
PTA 7-2 0/1背包问题(回溯法) 作者 王东 单位 贵州师范学院
0/1背包问题。给定一载重量为W的背包及n个重量为wi、价值为vi的物体,1≤i≤n,要求重量和恰好为W具有最大的价值。 输入格式: 第一行输入背包载重量W及背包个数n,再依次输入n行,每行为背包重量wi和价值vi。 输出格式: 第一行输出装入背包内…...

Matlab环形柱状图
数据准备: 名称 数值 Aa 21 Bb 23 Cc 35 Dd 47 保存为Excel文件后: % Load data from Excel file filename data.xlsx; % Ensure the file is in the current folder or provide full path dataTable readtable(filena…...

【AI大模型】探索GPT模型的奥秘:引领自然语言处理的新纪元
目录 🍔 GPT介绍 🍔 GPT的架构 🍔 GPT训练过程 3.1 无监督的预训练语言模型 3.2 有监督的下游任务fine-tunning 🍔 小结 学习目标 了解什么是GPT.掌握GPT的架构.掌握GPT的预训练任务. 🍔 GPT介绍 GPT是OpenAI公…...
5.Python爬虫相关
爬虫 爬虫原理 爬虫,又称网络爬虫,是一种自动获取网页内容的程序。它模拟人类浏览网页的行为,发送HTTP请求,获取网页源代码,再通过解析、提取等技术手段,获取所需数据。 HTTP请求与响应过程 爬虫首先向…...
Windows系统上配置eNSP环境的详细步骤
华为eNSP(Enterprise Network Simulation Platform)是一款针对华为数通网络设备的网络仿真平台,用于辅助工程师进行网络技术学习、方案验证和故障排查等工作。以下是在Windows系统上配置eNSP环境的详细步骤: 1. 准备工作 下载安…...

Database.NET——一款轻量级多数据库客户端工具
文章目录 Database.NET简介下载使用使用场景总结 Database.NET简介 Database.NET 是一个功能强大且易于使用的数据库管理工具,适用于多种数据库系统。它为开发者和数据库管理员提供了一个统一的界面,可以方便地管理和操作不同类型的数据库。 支持的数据…...

新浪微博C++面试题及参考答案
多态是什么?请详细解释其实现原理,例如通过虚函数表实现。 多态是面向对象编程中的一个重要概念,它允许不同的对象对同一消息或函数调用做出不同的响应,使得程序具有更好的可扩展性和灵活性。 在 C 中,多态主要通过虚函…...

计算机视觉目标检测-1
文章目录 摘要Abstract1.目标检测任务描述1.1 目标检测分类算法1.2 目标定位的简单实现思路1.2.1 回归位置 2.R-CNN2.1 目标检测-Overfeat模型2.1.1 滑动窗口 2.2 目标检测-RCNN模型2.2.1 非极大抑制(NMS) 2.3 目标检测评价指标 3.SPPNet3.1 spatial pyr…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果。…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...