【枚举】luogu_P2022 有趣的数
题意
考虑1到N的正整数集合。
把集合中的元素按照字典序排列,例如当N=11时,其顺序应该为:1,10,11,2,3,4,5,6,7,8,9。
定义\(K\)在\(N\)个数中的位置为\(Q(N,K)\),例如\(Q(11,2)=4\)。现在给出整数\(K\)和\(M\),要求找到最小的\(N\),使得\(Q(N,K)=M\)。
\(100\%\ 1\leq K,M\leq 10^9\)。
思路
先求出比\(k\)小的且字典序也比\(k\)小的数的个数,记为\(cnt\)。
判断\(cnt\)与\(m\)的关系。
如果\(cnt<m\),那么还要算上若干比k大的字典序比\(k\)小的数,按位数来枚举。
代码
/*例如235
先求出
1~2
10~23
100~235
之后再考虑
1000~2349
10000~23499
以此类推*/
signed main() {
scanf("%lld %lld", &k, &m);
f[0] = 1;
for (int i = 1; i <= 20; i++)
f[i] = f[i - 1] * 10;
int len = (int)log10(k) + 1;
for (int i = 1; i <= len; i++)
cnt += k / f[len - i] - f[i - 1] + 1;
if (m < cnt)
return !printf("0");
else if (m == cnt)
return !printf("%lld", k);
else {
for (int i = len + 1; i <= 20; i++)
if (k * f[i - len] - f[i - 1] + cnt < m)
cnt += k * f[i - len] - f[i - 1];
else
return !printf("%lld", m - cnt - 1 + f[i - 1]);
}
printf("0");
}

浙公网安备 33010602011771号