Beautiful Numbers

https://codeforces.com/problemset/problem/300/C

题目描述

Vitaly is a very weird man. He's got two favorite digits aa and bb . Vitaly calls a positive integer good, if the decimal representation of this integer only contains digits aa and bb . Vitaly calls a good number excellent, if the sum of its digits is a good number.

For example, let's say that Vitaly's favourite digits are 11 and 33 , then number 1212 isn't good and numbers 1313 or 311311 are. Also, number 111111 is excellent and number 1111 isn't.

Now Vitaly is wondering, how many excellent numbers of length exactly nn are there. As this number can be rather large, he asks you to count the remainder after dividing it by 10000000071000000007 (10^{9}+7)(109+7) .

A number's length is the number of digits in its decimal representation without leading zeroes.

输入格式

The first line contains three integers: aa , bb , nn (1<=a<b<=9,1<=n<=10^{6})(1<=a<b<=9,1<=n<=106) .

输出格式

Print a single integer — the answer to the problem modulo 10000000071000000007 (10^{9}+7)(109+7) .

题意翻译

Vitaly有一些奇怪的癖好,比如他特别爱两个小于10的数字a和b。Vitaly定义十进制表示下每一位都是a或b的数为“好数”,一个每一位数加起来为“好数”的“好数”被称为“极好的数”。

举个栗子=w=,如果偏爱数字为1和3,那么1212不是“好数”,13和311是“好数”,111是“极好的数”。

现在Vitaly想知道,长度为n(长度不包括前导0)的“极好的数”有多少个。对1e9+7取模。

n \leq 10^6n≤106

输入输出样例

输入 #1复制

1 3 3

输出 #1复制

1

输入 #2复制

2 3 10

输出 #2复制

165

思路:位置上的顺序是不影响和的,枚举一个长度为n的里面有多少个a,剩下的就是b,求一下和,然后check(长度最长为6,所以是常数复杂度)一下,然后对于a的个数进行组合数C(i/n)就好了.注意枚举是从0个开始的.

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e6+1000;
typedef long long ll;
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
ll fac[maxn];
ll p=mod;
ll a,b,n;
ll quick(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans=ans*a%p;
        a=a*a%p;
        b/=2;
    }
    return ans%p;
}
ll ccc(ll n,ll m){//求组合数
	if(m>n) return 0;
	return (fac[n] * quick(fac[m], p - 2) % p * quick(fac[n - m], p - 2) % p)%p ;
}
//ll lucas(ll n,ll m)
//{
//	if(!m) return 1;
//	return ccc(n%p,m%p)*lucas(n/p,m/p)%p;
//}
bool check(ll x)
{
	bool flag=1;
	while(x>0)
	{
		ll k=x%10;
		if(k!=a&&k!=b)
		{
			return false;
		}
		x/=10;
	}
	return true;
}
int main()
{
    cin.tie(0);std::ios::sync_with_stdio(false);
	//ccc(4,3);
	fac[0] = 1;
    for (ll i = 1; i <= maxn; i++){
        fac[i] = fac[i - 1] * i % p;
    }
    cin>>a>>b>>n;
    ll ans=0;
	for(ll i=0;i<=n;i++)
    {
    	ll sum=(a*i+b*(n-i));
    	if(check(sum))
    	{
    		ans=(ans%p+ccc(n,i)%p)%p;
		}
	}
	cout<<ans<<endl;
return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值