一、摘要

本文介绍了一种通过模拟寻找十进制镜像数字,然后判断其对应的k进制表示是否也是镜像的方法。具体来讲即从小到大遍历10进制的镜像数字,然后对10进制镜像数字转为k进制,然后判断转为k进制后是否还满足镜像。题解5933【C++】 800ms 三道简单题的组合对本题已经有较为详细的解释,若读者对本文有所疑问,可以阅读题解5933【C++】 800ms 三道简单题的组合

二、题解

本题主要分为三个小问题:

  1. 从小到大遍历10进制镜像数字;
  2. 将十进制镜像数字转为k进制表达;
  3. 判断k进制数字表达是否为镜像;

    其中小问题2.可以通过求余得到;问题3.可以通过穷举k进制数字各位得到结果。本文将主要对问题1.进行介绍。

为了从小到大遍历10进制镜像数字,我们可以依次讨论不同长度(位数)的数字:

  • 对于长度为1的所有10进制数字。所有数字都是镜像的(即数字1,2,3,4,5,6,7,8,9都是镜像的)。
  • 对于长度为奇数的10进制数字。例如,长度为5的所有10进制数字,其中镜像数字从小到大一定是:10'0'01, 10'1'01, 10'2'01, ..., 11'0'11, 12'1'21, ..., 99'0'99, ..., 99'9'99。

    可以看出,奇数长度的10进制镜像数字可以看成由pre+mid+suf三部分组成的(使用'符号分割的三部分),而且pre从10开始直到99,中间的mid对于任意pre都是从0到9,而suf正好是pre的反转。因此我们可以根据此规律从小到达求得长度为奇数的十进制镜像数字。
  • 类似的,对于长度为偶数的十进制数字。例如长度为6的所有十进制数字,其中的镜像数字从小到大一定是:100'001, 101'101, 102'201,..., 999'999。

    可以看出偶数长度的十进制镜像数字可以看成pre+suf两部分,而且pre从100开始一直到999,sufpre的反转。因此我们也可以根据此规律从小到大求得长度为偶数的10进制镜像数字。

至此,对于不同长度的10进制数字,我们都可以根据相应的规律从小到大求得该长度范围内的镜像数字,然后再判断其转为k进制后是否依旧为镜像数字,找到题目要求的n个满足条件的数字即可。

代码如下:

class Solution {
public:
vector<long long> p = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000};
long long myPow(int n){
return p[n];
}
// 判读数字num的k进制表示是否为镜像
bool isPalindrome(long long num, int k){
string nums; // 注意!此处一定要使用string类型记录各位数字,使用vector<int>会超时
while(num){
nums.push_back(num%k);
num /= k;
}
int n = nums.size();
for(int i=0; i<n/2; i++){
if(nums[i]!=nums[n-1-i]){
return false;
}
}
return true;
}
long long kMirror(int k, int n) {
long long ans = 0;
long long num = 1;
int len = 1;
while(true){
if(len==1){ // 1,2,3,4,5,6,7,8,9
for(int num=1; num<=9; num++){
if(isPalindrome(num, k)){
ans += num;
n --;
if(n<=0){
return ans;
}
}
}
len ++;
}else if(len%2==1){ // 长度为奇数的所有十进制镜像数字
int half_len = len/2;
long long num;
long long mid;
long long suf; long long min_lit = myPow(half_len-1); // 例如,对于长度为5的数字,pre从10开始遍历到99
long long max_lit = myPow(half_len); for(long long pre=min_lit; pre<max_lit; pre++){
// 根据pre计算得到suf,suf是pre的反转
long long temp_pre = pre;
long long t = myPow(half_len-1);
suf = 0;
while(temp_pre){
suf += (temp_pre%10)*t;
temp_pre /=10;
t /=10;
}
for(int mid=0; mid<10;mid++){
num = pre*myPow(half_len+1)+mid*myPow(half_len)+suf;
if(isPalindrome(num, k)){
ans += num;
n --;
if(n<=0){
return ans;
}
}
}
}
len ++;
}else{ // 长度为偶数的所有十进制镜像数字
int half_len = len/2;
long long num;
long long suf; long long min_lit = myPow(half_len-1); // 例如,对于长度为4的数字,pre从10开始遍历到99
long long max_lit = myPow(half_len); for(long long pre=min_lit; pre<max_lit; pre++){
long long temp_pre = pre;
long long t = myPow(half_len-1);
suf = 0;
while(temp_pre){
suf += (temp_pre%10)*t;
temp_pre /=10;
t /=10;
}
num = pre*myPow(half_len)+suf;
if(isPalindrome(num, k)){
ans += num;
n --;
if(n<=0){
return ans;
}
}
}
len ++;
}
}
return ans;
}
};

三、参考

[1.] 5933【C++】 800ms 三道简单题的组合

[LeetCode] 5933. k 镜像数字的和的更多相关文章

  1. [LeetCode] Find K Pairs with Smallest Sums 找和最小的K对数字

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...

  2. LeetCode:移除K位数字【402】

    LeetCode:移除K位数字[402] 题目描述 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. nu ...

  3. Leetcode 402.移掉k位数字

    移调k位数字 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : ...

  4. Leetcode 373.查找和最小的k对数字

    查找和最小的k对数字 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k. 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2. 找到和最小的 ...

  5. Java实现 LeetCode 440 字典序的第K小数字

    440. 字典序的第K小数字 给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字. 注意:1 ≤ k ≤ n ≤ 109. 示例 : 输入: n: 13 k: 2 输出: 10 解释: ...

  6. Java实现 LeetCode 402 移掉K位数字

    402. 移掉K位数字 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示 ...

  7. Java实现 LeetCode 373 查找和最小的K对数字

    373. 查找和最小的K对数字 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k. 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2. 找 ...

  8. [LeetCode] Find K Closest Elements 寻找K个最近元素

    Given a sorted array, two integers k and x, find the k closest elements to x in the array. The resul ...

  9. [Swift]LeetCode373. 查找和最小的K对数字 | Find K Pairs with Smallest Sums

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...

  10. 373 Find K Pairs with Smallest Sums 查找和最小的K对数字

    给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k.定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2.找到和最小的 k 对数字 (u1,v1 ...

随机推荐

  1. mybatis批量插入支持默认值和自定义id生成策略的免写sql插件

    最近做项目时用了免写sql的插件但是发现批量操作不满足现有需求.所以,在原有基础之上扩展了批量的操作支持[支持插入默认值和自定义id生成策略].使用方法如下: 一:在pom文件中引入jar配置 < ...

  2. 尴尬:在zoom中找不到会议密码

    临时要开一个zoom会议,点击"新会议"进入,然后邀请其他与会者. "会议" - "复制邀请链接", 得到一行这样的信息(会议号已模糊处理) ...

  3. [MyArch]我的Archlinux与bspwm的重生之途

    0x00 前言碎语 2023.8.19 好久不见.这些日子一直在和bspwm和archlinux打交道.自从上次NepCTF的前几天和CuB3y0nd小师傅的bspwm配置打交道之后我一发不可收拾.中 ...

  4. 浅谈高维FWT

    概述 快速沃尔什变换,可以用来处理有关异或卷积的问题. 而异或运算,也就是二进制下的不进位加法运算,我们考虑能否将其拓展到高维. 也就是,在 \(k\) 进制下的不进位加法卷积. 对于具体的某一位,我 ...

  5. jq 完成复选框的全选和全不选,并组装成数组发送到后台

    jQuery 代码实现,HTML dom节点对应js的id 即可 <script> $(function() { //复选框全选和全不选 $("#selectAll") ...

  6. 【Unity3D】灯光组件Light

    1 灯光简介 ​ 在 Hierarchy 窗口右键,选择 Light,再选择具体的灯光类型,在 Inspector 窗口查看灯光组件如下: Type:灯光类型,主要有:Directional(平行光) ...

  7. JSP使用FileUpload上传文件设置setSizeMax后连接被重置

    今天在学习利用JSP+Servlet+FileUpload开发文件上传功能.在设置了上传文件最大限制为10M以后,选择了3M的pdf上传提交后连接被重置了... 我的代码: //设置上传单个文件的大小 ...

  8. B - Bracket Sequence题解

    B - Bracket Sequence 思路: 用一个flag来标记括号的数目,如果括号数目是个偶数的话,就代表当前要执行'+'操作,反之就是'*'操作.对于最外层的数,是没有计算的. 所以最后要单 ...

  9. acm交互题

    1.Dragon Balls 根据勾股定理把所有整数点都给求解出来,然后依次询问,注意数据范围 暴力求解,把每次可能的值都求出来,然后逐个比较. #include<bits/stdc++.h&g ...

  10. 项目实战:Qt监测操作系统cpu温度v1.1.0(支持windows、linux、国产麒麟系统)

    需求   使用Qt软件开发一个检测cpu温度的功能.  兼容windows.linux,国产麒麟系统(同为linux) Demo   windows上运行(需要管理员权限):     国产麒麟操作上运 ...