构造

很容易发现,当 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;
}