构造
很容易发现,当 2 * n 每进1位的时候,与 2 * S(n)的差就会少去9,这也可以推出来,因为满10进1,每进1位就会少10,得到1,所以每进1位就会少9.所以当n的数位上出现[5-9]时,乘于2就会少9,假设n的所有位上一共有L个[5-9]的数
我们可以得到 S(2n)=2*S(n)-L*9
再由 a×S(n)=b×S(2n)
,所以 L/S(n)=(2*b-a)/(9*b)
。(注意要上下同除gcd)
所以我们可以让 L=2*b-a,S(n)=9*b
,那如何贪心构造出最小的n呢?
我们先让n中的L位数全为5,即 xxx555(L个5),S(n)-5 * L,然后剩下的S(n)再从末尾不断的加上去。
当L<0||5 * L>S(n)
的时候就是无解。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 2e5 + 10;
int a, b;
int gcd(int a, int b)
{
if (b == 0) return a;
return gcd(b, a%b);
}
int ans[N];
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &a, &b);
int d = gcd(a, b);
a /= d, b /= d;
int l = 2 * b - a, sn = 9 * b;
if (l<0 || l * 5>sn){
puts("0");
continue;
}
d = gcd(l, sn);
l /= d, sn /= d;
int tot = 0;
sn -= 5 * l;
for (int i = 0; i < l; i++)
{
int tmp = min(4, sn);
ans[tot++] = 5 + tmp;
sn -= tmp;
}
while (sn)
{
int tmp = min(4, sn);
ans[tot++] = tmp;
sn -= tmp;
}
for (int i = tot - 1; i >= 0; i--)
cout << ans[i];
puts("");
}
return 0;
}
评论