题意:
给出n个人的id,有两个门,每一个门有一个标号。我们记作a和b,如今我们要将n个人分成两组,进入两个门中,使得两部分人的标号的和(迭代的求,直至变成一位数。我们姑且叫做求“和”操作~)各自等于a和b,问有多少种分法。
思路:
非常easy想到。假设能找到满足题意的解。一定满足a和b的和等于n个人的标号的和,所以我们仅仅须要推断n个人的标号组成a的情况有多少(或者仅仅推断b,一样),同一时候还要注意能够把n个人都分给a,或者都分给b,这样也是满足的。
详细的细节都在代码里了,一看应该就能懂~~
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100005;
#define mod 258280327
int SUM(int x,int y)
{
int tmp=x+y;
int ans=tmp%9;
if(ans==0)
return 9;
return ans;
}
int num[maxn];
int dp[maxn][10];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,a,b;
scanf("%d%d%d",&n,&a,&b);
int sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
sum=SUM(sum,num[i]);
}
memset(dp,0,sizeof dp);
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=9;j++)
{
dp[i][j]+=dp[i-1][j];
dp[i][SUM(num[i],j)]+=dp[i-1][j];
dp[i][j]%=mod;
dp[i][SUM(num[i],j)]%=mod;
}
}
int ans=0;
if(SUM(a,b)==sum)
{
ans+=dp[n][a];
if(a==sum)
ans--;
}
if(a==sum)
ans++;
if(b==sum)
ans++;
printf("%d\n",ans);
}
return 0;
}