...刚开始没看清题意,,原来excellent的前提是good...
我们来认为那个长度为n位的数字为A,A的每一位之和称为B
首先,我们需要分两种情况来讨论。
第一种情况,当a等于b时,说明A里那n位数字全部是a
也就是说,B的值等于a*n,我们只需要验证现在B中每一位的数字是否都等于a就可以了
如果都等于,那么答案就是1,否则答案就是0
第二种情况,当a不等于b时
设a在A中出现了x次,b在A中出现了y次。
因为A的长度是n,所以肯定有x+y = n
B是由A的每一位数字相加而成,所以B最大也只可能是9 * n,也就是n位数中每一位都为9
但是B中只能有a和b两个数字,说明B的个数并不算太多,最多就几千个,所以可以直接暴力枚举出B
又知道,a在A中出现了x次,b在A中出现了y次。B是A中每个数字之和,A中只有a和b。。。
说到这里,很明显了,B=a*x+b*y
所以,x+y = n,B=a*x+b*y,可以直接解出x和y
如果发现x和y不为整数或者有一个小于0,那么就说明这一种B是不满足情况的忽略就行
那么,现在我们已经知道当B为一种情况的时候,x和y的数量了,怎么求种类数呢
其实就是在n个位置中选择x个位置放数字a,其他的位置必须也只能放数字b了,所以就是C(n,x)
绕了一大圈,最后思路非常清晰了
1.特断
2.DFS枚举数字B
3.解方程,得到x和y
4.把所有满足条件的情况,求C(n,x),并累加取模就是答案
那么如何求C呢,,这个可以百度一下 逆元
这里我直接贴上模板,,以后遇到求组合数,就算暂时理解不了原理,也可以直接打模板了
const int MX = 1000000 + 5;//n的大小 const int mod = 1e9 + 7;//如果模不为质数,这个模板是不能用的!! LL F[MX], invF[MX]; LL power(LL a, LL b) { LL ret = 1; while(b) { if(b & 1) ret = (ret * a) % mod; a = (a * a) % mod; b >>= 1; } return ret; } void init() {//这个是用来初始化的,记得 F[0] = 1; for(int i = 1; i < MX; i++) { F[i] = (F[i - 1] * i) % mod; } invF[MX - 1] = power(F[MX - 1], mod - 2); for(int i = MX - 2; i >= 0; i--) { invF[i] = invF[i + 1] * (i + 1) % mod; } } LL C(int n, int m) { if(n < 0 || m < 0 || m > n) return 0; if(m == 0 || m == n) return 1; return F[n] * invF[n - m] % mod * invF[m] % mod; } LL A(int n, int m) { if(n < 0 || m < 0 || m > n) return 0; return F[n] * invF[n - m] % mod; }
#include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int MX = 1000000 + 5; const int mod = 1e9 + 7; LL F[MX], invF[MX]; LL power(LL a, LL b) { LL ret = 1; while(b) { if(b & 1) ret = (ret * a) % mod; a = (a * a) % mod; b >>= 1; } return ret; } void init() {//这个是用来初始化的,记得 F[0] = 1; for(int i = 1; i < MX; i++) { F[i] = (F[i - 1] * i) % mod; } invF[MX - 1] = power(F[MX - 1], mod - 2); for(int i = MX - 2; i >= 0; i--) { invF[i] = invF[i + 1] * (i + 1) % mod; } } LL C(int n, int m) { if(n < 0 || m < 0 || m > n) return 0; if(m == 0 || m == n) return 1; return F[n] * invF[n - m] % mod * invF[m] % mod; } LL A(int n, int m) { if(n < 0 || m < 0 || m > n) return 0; return F[n] * invF[n - m] % mod; } bool check(int n, int x) { while(n) { if(n % 10 != x) return false; n /= 10; } return true; } int a, b, n; LL solve(int z) { if((z - a * n) % (b - a)) return 0; int y = (z - a * n) / (b - a); return C(n, y); } LL DFS(int x) { if(x > 9 * n) return 0; LL ans = solve(x); ans += DFS(10 * x + a); ans += DFS(10 * x + b); ans %= mod; return ans; } int main() { //freopen("input.txt", "r", stdin); init(); scanf("%d%d%d", &a, &b, &n); if(a == b) { if(check(a * n, a)) printf("1\n"); else printf("0\n"); return 0; } printf("%I64d\n", DFS(0)); return 0; }