数位dp+二分
比较入门的数位dp,快半年没写过拿来练练手。
dp是三维,分别是位置,当前数mod7,是否含有7,前两个很简单,第三位有点迷惑,好像没有什么用,但仔细一想,在低位的时候有时相同的pos和tot也会存在值不一样的情况,比如18和27,一个是4一个是6。所以只有这两个一起才能保证每个值都对应。
//
// Created by acer on 2021/5/11.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
int num[20];
ll dp[20][10][2];
ll dfs(int pos, bool limit, bool h_7, int tot) {
if (pos < 0) {
return (h_7 || (tot % 7 == 0));
}
if (dp[pos][tot][h_7] != -1 && !limit) return dp[pos][tot][h_7];
int ub = limit ? num[pos] : 9;
ll tmp = 0;
for (int i = 0; i <= ub; ++i) {
tmp += dfs(pos - 1, limit && i == ub, i == 7 || h_7, (tot * 10 + i) % 7);
}
if (!limit) dp[pos][tot][h_7] = tmp;
return tmp;
}
ll cal(ll x) {
memset(dp, -1, sizeof(dp));
memset(num, 0, sizeof(num));
int pos = 0;
while (x) {
num[pos++] = x % 10;
x /= 10;
}
return dfs(pos - 1, true, false, 0);
}
signed main() {
ll m, n;
while (cin >> m >> n) {
ll ans = 0;
ll r = (ll) 1e18;
ll l = m;
ll p = cal(m);
while (l <= r) {
ll mid = (l + r) >> 1;
if (cal(mid) - p >= n) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
cout << l << endl;
}
}