Problem Description
Acesrc is a famous mathematician at Nanjing University second to none. Playing with interesting numbers is his favorite. Today, he finds a manuscript when cleaning his room, which reads
... Let f(d,n) denote the number of occurrences of digit d in decimal representations of integers 1,2,3,⋯,n. The function has some fantastic properties ...
... Obviously, there exist some nonnegative integers k, such that f(d,k)=k, and I decide to call them d-good numbers ...
... I have found all d-good numbers not exceeding 101000, but the paper is too small to write all these numbers ...
Acesrc quickly recollects all d-good numbers he found, and he tells Redsun a question about d-good numbers: what is the maximum d-good number no greater than x? However, Redsun is not good at mathematics, so he wants you to help him solve this problem.
Input
The first line of input consists of a single integer q (1≤q≤1500), denoting the number of test cases. Each test case is a single line of two integers d (1≤d≤9) and x (0≤x≤1018).
Output
For each test case, print the answer as a single integer in one line. Note that 0 is trivially a d-good number for arbitrary d.
Sample Input
3
1 1
1 199999
3 0Sample Output
1
199990
0
题意:t 组数据,定义函数 f(d,n) 为 1~n 的十进制位中数字 d 出现的个数,每组给出 d、x 两个数,现在要在 1~x 中找一个最大的 k,使得 f(d,k)=k,求这个 k
思路:
首先计算 f(d,x),如果 f(d,x)=x,那么自然就是结果
如果 f(d,x)<x,由于 f(d,x) 与 x 之间的数一定是大于想求的结果的,那么就可以把 x 赋值为 f(d,x),再次代入求结果,直到 f(d,x)=x 为止
如果 f(d,x)>x,最坏的情况下,数的长度为 m 位,所有的位数都是 d,那么如果想让 f(d,x) 与 x 相等,至少要让他减去 f(d,x)-x/m 个数,因此在这种情况下,只要让 x=x-(f(d,x)-x)/m 即可
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickMultPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL quickPowMod(LL a,LL b,LL mod){ LL res=1; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1; } return res; }
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 1000000000+7;
const int N = 500000+5;
const int dx[] = {0,0,-1,1,1,-1,1,1};
const int dy[] = {1,-1,0,0,-1,1,-1,1};
using namespace std;
LL f(LL n, LL x) { //计算1~n中,x出现的次数
LL cnt = 0, k;
for (LL i = 1; k = n / i; i *= 10) {
cnt += (k / 10) * i;
LL cur = k % 10;
if (cur > x)
cnt += i;
else if (cur == x)
cnt += n - k * i + 1;
}
return cnt;
}
LL getLen(LL n) { //获取n的长度
LL len = 0;
while (n) {
len++;
n /= 10;
}
return len;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
LL d, x;
scanf("%lld%lld", &d, &x);
while (true) {
LL n = f(x, d);
if (n == x) {
printf("%lld\n", n);
break;
}
else if (n < x)
x = n;
else{
LL m=getLen(n);
x = x - max((n - x) / m, 1LL);
}
}
}
return 0;
}