代码中有详细解释,cnt要使用long long int(害我找了好久):joy:

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll m, n, cntn, cntx, dp[20][10][2];
int bit[20];

ll DFS(int pos, int remain, bool isMax, bool hasSeven) {
    //pos:位数, remain:上一位残留下来的余数, isMax:上一位是否达到了最大值, hasSeven记录是否位数上是否出现过7
    if(pos == 0) {
        return (!remain) || hasSeven;
    }
    //若余数不为0,则说明不能被7整除,不计数,否则计数
    if(!isMax && dp[pos][remain][hasSeven]) return dp[pos][remain][hasSeven];
    //若上一位不为最大值,且相同位数、相同余数的情况已经计算过,那么直接拿来用就好
    int maxNum = isMax ? bit[pos] : 9;
    ll cnt = 0;
    //上一位为最大值时,这一位的取数将受到bit[pos]的限制
    for(int i = 0; i <= maxNum; i++){
        //if(!hasSeven && i == 7) cnt++;
        cnt += DFS(pos - 1, (i + 10 * remain) % 7, isMax && i == maxNum, hasSeven || i == 7);
    }
    return isMax ? cnt : dp[pos][remain][hasSeven] = cnt;
    //不是最大值,把数据记录下来才有意义
}

ll tran(ll num) {
    int pos = 0;
    while(num){
        bit[++pos] = num % 10;
        num /= 10;
    }
    return DFS(pos, 0, true, false);
}

int main() {
    cin>>m>>n;
    cntn = tran(m);//记录到m时已经拍掌的次数
    //cout<<cntn<<endl;
    ll ri = m + n * 7 + 7;//右边界
    ll le = m;
    ll mid;
    while(le <= ri) {
        mid = (le + ri) / 2;
        if (tran(mid) - cntn >= n) {
            ri = mid - 1;
        } else {
            le = mid + 1;
        }
    }
    cout<<le<<endl;
    return 0;
}