专栏文章

题解:CF300C Beautiful Numbers

CF300C题解参与者 2已保存评论 3

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
3 条
当前快照
1 份
快照标识符
@miqhgzrv
此快照首次捕获于
2025/12/04 04:52
3 个月前
此快照最后确认于
2025/12/04 04:52
3 个月前
查看原文
Beautiful Numbers 题解
首先,我们观察题面,可以发现每个极好的数都必须是好数。 那好数的 nn 位加起来是好数那就是极好的数。
我们可以枚举 aa 出现了 sumasuma 次,则 bb 出现了 nsuman - suma 次也就是 sumbsumb,如果 a×suma+b×sumba \times suma + b \times sumb 是好数,那这个数就是极好的数。
那我们可以求解出长度为 nnaa 出现 sumasumabb 出现 sumbsumb 次的数有多少个。也就是 C(n,suma)C(n,suma)C(n,sumb)C(n,sumb)
最后奉上代码:
CPP
#include <iostream>
using namespace std;
long long const P = 1000000007;
int  n, a, b;
long long ans=0, fact[1000005], inv[1000005], finv[1000005];

int C(int n, int m)//组合数的计算 
{
	if(n < m) 
		return 0;
	if(m == 0)
	    return 1;
	return fact[n] * finv[m] % P * finv[n - m] % P;
 } 
bool check(int x){//检查一下每一位加起来是不是好数 
	while (x){
		if (x % 10 != a && x % 10 != b) return false;
		x /= 10;
	}
	return true;
}
int main()
{
	scanf("%d%d%d",&a,&b,&n);
    fact[0] = 1;
    for (int i = 1; i <= n; i++)
        fact[i] = fact[i - 1] * i % P;//计算阶乘 
    finv[0] = finv[1] = inv[1] = 1;
    for (int i = 2; i <= n; i++)
    {
    	int k=P/i, r=P%i; 
        inv[i] = ((-1 * k * inv[r] % P) + P) % P;//逆元 
        finv[i] = finv[i - 1] * inv[i] % P;//逆元的阶乘 
    }
    for (int suma = 0;suma <= n;suma++){
    	int sumb = n - suma;
    	if (check(sumb * b + suma * a)){
    		ans = (ans + C(n,suma) % P) % P;//多模几下没问题 
		}
	}
    cout<<ans;
    return 0;//华丽收场 
}

评论

3 条评论,欢迎与作者交流。

正在加载评论...