当前位置: 首页 > news >正文

【数论】3260. 找出最大的 N 位 K 回文数|2370

本文涉及知识点

C++动态规划
数论:质数、最大公约数、菲蜀定理

LeetCode3260. 找出最大的 N 位 K 回文数

给你两个 正整数 n 和 k。
如果整数 x 满足以下全部条件,则该整数是一个 k 回文数:
x 是一个 回文数。x 可以被 k 整除。以字符串形式返回 最大的 n 位 k 回文数。
注意,该整数 不 含前导零。
示例 1:
输入: n = 3, k = 5
输出: “595”
解释:
595 是最大的 3 位 k 回文数。
示例 2:
输入: n = 1, k = 4
输出: “8”
解释:
1 位 k 回文数只有 4 和 8。
示例 3:
输入: n = 5, k = 6
输出: “89898”
提示:
1 <= n <= 105
1 <= k <= 9

数论

v1[i]记录 10i%k,x=其和乘以9%k就是最大n位数%k,最大的n位数是各位都是9。如果x等于0,最大的9位数就是本题答案。
v1[0]=1%k,v1[i] = (v1[i-1]*10)%k。
x ∈ \in [0,k] ,而k<=9。
错误性质一:如果n是奇数,将最中间的9减少x,就是回文,且被k整除。错误原因:中间的减少x,结果不一定减少x,而是x × \times × v[n/2]。
n2=(n+1)/2。由于左右部分完全对称,故我们只需要枚举左半部分减少了i。但这个时间复杂度:O(10n2),超时。

动态规划

我们令整个字符串为ans,左半部分为s。

动态规划的状态表示

dp[i][j] 记录s长度为i的后缀,除最左的位外可以减少任意次,最左的位最少减少多少次使得str总共减少%k == j。空间复杂度:O(nk)

动态规划的填表顺序

枚举前置状态和当前状态。i = 0 to i<n2

动态规划的填报顺序

如果dp[i][j]是10,忽略。

int t = v1[i1];if (i1 != i2) { t += v1[i2]; }				t = (t*m + j) % k;

i 是s 从右向左的下标,从0开始。其在左半部分对应ans[j1],右半部分对应ans[j2]。
MinSelf(dp[i+1][t] , m) 更新dp1的时候,同时更新dp2 dp2[i+1][t] = j

动态规划的初始值

dp[0][0]=0,其它全为10。

动态规划的返回值

dp[i+1][x] < 10结束 fun(i+1,x)
fun(p,x)
q =p to 1
m = dp[q][x]
s 倒数第q-1位 减少m,str右半部分也要做响应减少。
x = dp2[q][x]

代码

class Solution {public:string largestPalindrome(int n, int k) {vector<int> v1(n,1%k);for (int i = 1; i < n; i++) {v1[i] = v1[i - 1] * 10 % k;}const int x = accumulate(v1.begin(), v1.end(), 0)*9 % k;if (0 == x) {  return string(n,'9'); }const int n2 = (n+1) / 2;			vector<vector<int>> dp(n2 + 1, vector<int>(k, 10));auto dp2 = dp;dp[0][0] = 0;int i1 = n2-1;int i2 = n/2;for (int i = 0; i < n2;i++,i1--,i2++) {for (int j = 0; j < k; j++) {if (10 == dp[i][j]) { continue; }for (int m = 0; m < k; m++) {int t = v1[i1];if (i1 != i2) { t += v1[i2]; }				t = (t*m + j) % k;if (m < dp[i + 1][t]){dp[i + 1][t] = m;dp2[i + 1][t] = j;}		}}if (dp[i + 1][x] < 10) {string ans(n2, '9');auto DoS = [&](int p, int x) {							for (; p > 0; p--) {int m = dp[p][x];			ans[n2- 1 - (p-1)] -= m;x = dp2[p][x];}};						DoS(i + 1, x);string right(ans.begin(), ans.begin() + (n - n2));ans += string(right.rbegin(), right.rend());return ans;}}return "";}};

核心代码

	int n, k;TEST_METHOD(TestMethod11){n = 3, k = 5;auto res = Solution().largestPalindrome(n, k);AssertEx(string("595"), res);}TEST_METHOD(TestMethod12){n = 1, k = 4;auto res = Solution().largestPalindrome(n, k);AssertEx(string("8"), res);}TEST_METHOD(TestMethod13){n = 5, k = 6;auto res = Solution().largestPalindrome(n, k);AssertEx(string("89898"), res);}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

相关文章:

  • 老婆是用来爱的,不是用来吼的
  • 探秘Python 工匠:案例、技巧与工程实践:解锁Python进阶的通关秘籍
  • Mixture-of-Experts with Expert Choice Routing:专家混合模型与专家选择路由
  • LeetCode 1365. 有多少小于当前数字的数字 java题解
  • @EnableAsync+@Async源码学习笔记之一
  • C语言格式化输入输出总结 (printf和scanf)
  • ubuntu18.04安装QT问题汇总
  • 【STM32单片机】#10 USART串口通信
  • Kubernetes 多主多从集群部署完整文档
  • 解码 Web Service:从技术原理到应用场景的深度剖析
  • (2)Vue事件绑定的使用
  • 测试第四课---------性能测试
  • JAVA IO、BIO、NIO、AIO及零拷贝
  • 数据从辅存调入主存,页表中一定存在
  • LinearLayout 线性布局
  • 6.7 ChatGPT自动生成定时任务脚本:Python与Cron双方案实战指南
  • dac直通线还是aoc直通线? sfp使用
  • Shell脚本-什么时候需要定义变量
  • 【2025】Datawhale AI春训营-蛋白质预测(AI+生命科学)-Task2笔记
  • 实战交易策略 篇十六:猎豹阿杜打板交易策略
  • 美伊第二轮核问题间接谈判结束,伊方称“结果是建设性的”
  • 马上评|机器人马拉松,也是具身智能产业的加速跑
  • 外交部:中方在乌克兰问题上一直积极致力于劝和促谈
  • 嵩山少林风景区女游客进男厕:不能止步于批评
  • 工信部:加快推进6G技术研发等,前瞻布局和培育面向6G的应用产业生态
  • 农文旅项目投资1700万后被告知是禁养区?南京浦口通报