【枚举】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");
}
posted @ 2021-07-14 22:03  nymph181  阅读(61)  评论(0)    收藏  举报