1. 程式人生 > >JZOJ 3056. 【NOIP2012模擬10.27】數字

JZOJ 3056. 【NOIP2012模擬10.27】數字

define 個數字 表示 ring rain tput desc vector ++

題目

Description

【問題描述】


一個數字被稱為好數字當他滿足下列條件:


1. 它有2*n個數位,n是正整數(允許有前導0)


2. 構成它的每個數字都在給定的數字集合S中。


3. 它前n位之和與後n位之和相等或者它奇數位之和與偶數位之和相等


例如對於n=2,S={1,2},合法的好數字有1111,1122,1212,1221,2112,2121,2211,2222這樣8種。


已知n,求合法的好數字的個數mod 999983。


Input

第一行一個數n。


接下來一個長度不超過10的字符串,表示給定的數字集合。


Output

一行一個數字表示合法的好數字的個數mod 999983。


Sample Input

2
0987654321

Sample Output

1240

Data Constraint

Hint

對於20%的數據,n≤7。


對於100%的.據,n≤1000,|S|≤10。

分析

  • 答案其實是

  • 前n位之和與後n位之和相等+它奇數位之和與偶數位之和相等-兩個都有的
  • 前兩種很好求,遞推就好了
  • 第三種其實就是

    因為前n位之和=後n位之和,奇數位之和=偶數位之和

    所以前n位中奇數位之和=後n位中偶數位之和 且

    前n位中偶數位之和=後n位中奇數位之和

代碼

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6
#include<cmath> 7 #include<vector> 8 #define mod 999983 9 #define ll long long 10 using namespace std; 11 inline ll read() 12 { 13 ll x=0,f=1;char ch=getchar(); 14 while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();} 15 while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();} 16 return x*f; 17 } 18 int n; 19 char ch[15]; 20 int a[15]; 21 int f[1005][9005]; 22 ll ans; 23 ll cal(int x) 24 { 25 ll ans=0; 26 for(int i=0;i<=x*9;i++) 27 if(f[x][i]) 28 ans=(ans+((ll)f[x][i]*f[x][i]))%mod; 29 return ans; 30 } 31 int main() 32 { 33 n=read(); 34 scanf("%s",ch); 35 int l=strlen(ch); 36 for(int i=0;i<l;i++) 37 a[i+1]=ch[i]-0; 38 f[0][0]=1; 39 for(int i=0;i<n;i++) 40 for(int j=0;j<=n*9;j++) 41 if(f[i][j]) 42 for(int k=1;k<=l;k++) 43 f[i+1][j+a[k]]=(f[i+1][j+a[k]]+f[i][j])%mod; 44 ans=2*cal(n)-cal(n/2)*cal(n-n/2); 45 printf("%d",(ans%mod+mod)%mod); 46 return 0; 47 }

JZOJ 3056. 【NOIP2012模擬10.27】數字