P9006 [入门赛 #9] 神树大人挥动魔杖 (hv)
Nostopathy · · 题解
看了题解区各位大神的题解,蒟蒻表示看不懂,于是写一篇详细易懂的题解。
Analysis
我们需要求所有
那么想怎么不枚举所有数,可以发现当前的数可以是上一个数加一位数得来的,而假如以前的余数是
定义
现在看问题,对于所有
那么首位从
所以对给定的
最后注意
::::success[Code]
我使用了 vector 和空行让代码看起来更舒服。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e8 + 7;
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n, k;
cin >> n >> k;
int p10 = 1;
for(int i = 1; i < n; ++ i)
p10 = (p10 * 10) % k;
vector<vector<int> > f(n + 1, vector<int>(k, 0));
for(int d = 0; d <= 9; ++ d)
++ f[1][d % k];
for(int m = 2; m < n; ++ m)
for(int rp = 0; rp < k; ++ rp){
if(f[m - 1][rp] == 0)
continue;
int t = rp * 10 % k;
for(int d = 0; d <= 9; ++ d){
int rn = (t + d) % k;
f[m][rn] = (f[m][rn] + f[m - 1][rp]) % mod;
}
}
if(n == 1){
for(int r = 0; r < k; ++ r){
int cnt = 0;
for(int d = 1; d <= 9; ++ d)
if(d % k == r)
++ cnt;
cout << cnt % mod << " ";
}
return 0;
}
vector<int> ans(k, 0);
for(int d = 1; d <= 9; ++ d){
int base = d * p10 % k;
for(int r = 0; r < k; ++ r){
int nr = (r - base + k) % k;
ans[r] = (ans[r] + f[n - 1][nr]) % mod;
}
}
for(int r = 0; r < k; ++ r)
cout << ans[r] << " ";
return 0;
}
::::
Thanks.