[Jzoj] 3056.数字

本文探讨了好数字的概念及计数方法,好数字需满足特定的数学条件,文章详细解析了如何通过递推算法高效计算好数字的总数,并提供了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

一个数字被称为好数字当他满足下列条件:

  1. 它有2∗n2*n2n个数位,nnn是正整数(允许有前导000)
  2. 构成它的每个数字都在给定的数字集合SSS中。
  3. 它前nnn位之和与后nnn位之和相等或者它奇数位之和与偶数位之和相等

已知n,求合法的好数字的个数mod 999983。

题目解析

ans=ans=ans=前n位之和与后n位之和相等的方案数+奇数位之和与偶数位之和相等的方案数-前n位之和与后n位之和相等且奇数位之和与偶数位之和相等的方案数

前2个需要+的方案数都很好求,直接递推

重点是最后一个要满足2个条件的方案数怎么求,其实也很简单:

因为前n位之和=后n位之和,奇数位之和=偶数位之和

所以前n位中奇数位之和=后n位中偶数位之和 且 前n位中偶数位之和=后n位中奇数位之和

现在只要求上面这个问题的方案数,由于两个等式中的元素无交集,也是十分好算的。

代码

#include<bits/stdc++.h>
#define M 999983
#define L long long
using namespace std;
L n,len,ans,l1,l2,ans1,ans2;
L a[11],f[1005][10005];
string s;
int main()
{
	cin>>n>>s;
	len=s.size();
	for(int i=0;i<len;i++)
	 a[i+1]=s[i]-48;
	f[0][0]=1;
	for(int i=1;i<=n;i++)
	 for(int j=0;j<=i*9;j++)
	  for(int k=1;k<=len;k++)
	   if(j-a[k]>=0)
	    (f[i][j]+=f[i-1][j-a[k]])%=M;
	for(int i=0;i<=n*9;i++)
	 (ans+=2*f[n][i]*f[n][i])%=M;
	l1=(n+1)/2;l2=n/2;
	for(int i=0;i<=l1*9;i++)
	 (ans1+=f[l1][i]*f[l1][i])%=M;
	for(int i=0;i<=l2*9;i++)
	 (ans2+=f[l2][i]*f[l2][i])%=M;
	ans=(ans-ans1*ans2%M+M)%M;
	cout<<ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值