明七暗七
阿新 • • 發佈:2020-08-01
題目描述
今天是個特殊的日子,CSL和他的小夥伴們圍坐在一張桌子上玩起了明七暗七的遊戲。遊戲規則是這樣的:一個人報出一個起始數,接下來按照逆時針的順序輪流報數,如果碰到數是7的倍數或含有7,則拍手,下一個人接著報數。直到有一個人報錯了數字或者沒有及時拍手為止。
玩遊戲嘛,當然得有懲罰。這麼簡單的遊戲對CSL的學霸小夥伴而言實在是太無腦了,輕輕鬆鬆數到上萬根本不在話下。但是對於數學是體育老師教的CSL來說,實在是太難了。快幫他算算什麼時候應該拍手吧。
輸入描述:
輸入兩個整數m和n。(1 ≤ m, n ≤ 1012)
輸出描述:
輸出一個整數,表示m以後第n個需要拍手的數字。
輸入
30 7
輸出
57
輸入
56 1
輸出
57
#include<bits/stdc++.h> using namespace std; const int N = 20; typedef long long LL; LL dim[N], dp[N][10][2]; LL dfs(int pos, int sum, int f, int lim) { if (pos < 0) return (!sum || f); if (!lim && ~dp[pos][sum][f]) return dp[pos][sum][f];int up = lim ? dim[pos] : 9; LL ret = 0; for (int i = 0; i <= up; i++) { ret += dfs(pos - 1, (sum * 10 + i) % 7, f || i == 7, lim && i == up); } if (!lim) dp[pos][sum][f] = ret; return ret; } LL solve(LL x) { memset(dp, -1, sizeof(dp)); memset(dim, 0, sizeof(dim));int len = 0; while (x) { dim[len++] = x % 10; x /= 10; } return dfs(len - 1, 0, 0, 1); } int main() { LL m, n; cin >> m >> n; LL st = solve(m); LL l = 0, r = 1e18, ret; while (l <= r) { LL k = (l + r) >> 1; LL temp = solve(k); if (temp >= st + n) r = k - 1, ret = k; else l = k + 1; } printf("%lld\n", ret); return 0; }