学习C++从娃娃抓起!记录下蓝桥杯备考比赛学习过程中的题目,记录每一个瞬间。
附上汇总贴:蓝桥杯备考冲刺必刷题(C++) | 汇总-CSDN博客
【题目描述】
给定一个整数
n
n
n,请你在
1
1
1到
n
n
n中找出字典序排序后第
k
k
k个数字。例如,当
n
n
n为
11
11
11,
k
k
k为
3
3
3时,字典序如下:
1
,
10
,
11
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
1,10,11,2,3,4,5,6,7,8,9
1,10,11,2,3,4,5,6,7,8,9
因此,第
3
3
3个数字是
11
11
11。
【输入】
输入两个整数
n
n
n和
k
k
k,
(
1
≤
n
,
k
≤
1
0
9
)
(1\le n,k\le 10^9)
(1≤n,k≤109)。
【输出】
输出一个整数,表示字典序排列后第
k
k
k个数字。
【输入样例】
13 2
【输出样例】
10
【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, k, res;
int calc(int n, int n1, int n2) // 以n1为前缀,求有多少数字在序列中,即有多少数字比n小
{
int steps=0;
while (n1<=n) {
steps += min(n+1, n2) - n1; // 计算合法数字的个数
n1 *= 10; // n1和n2继续扩大验证
n2 *= 10;
}
return steps;
}
int find(int n, int k)
{
int cur = 1; // cur有两种变化,加1或乘10
k = k-1; // 若k为1,则直接输出1
while (k>0) {
int steps = calc(n, cur, cur+1); // 计算有多少以cur为前缀的数字在序列中
if (steps<=k) { // 以cur为前缀的所有数字均在n左侧
cur += 1; // 更新前缀
k -= steps; // 减去前面已经累计的步长
} else { // n在以cur为前缀的所有数字组成的集合中
cur *= 10; // 延长前缀,后面会递归到steps<=k的情况中
k -= 1; // 步长减1
}
}
return cur; // 最终cur是第k个数
}
signed main()
{
cin >> n >> k;
res = find(n, k);
cout << res << endl;
return 0;
}
【运行结果】
13 2
10