HDU 5651 xiaoxin juju needs help 水题一发

分析:求一下组合数

首先,如果不止一个字符出现的次数为奇数,则结果为0。

否则,我们把每个字符出现次数除2,也就是考虑一半的情况。

那么结果就是这个可重复集合的排列数了。 fact(n)/fact(a_1)/fact(a_2)/..../fact(a_n)fact(n)/fact(a1​​)/fact(a2​​)/..../fact(an​​)

#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=1e3+5;
const int INF=0x3f3f3f3f;
const LL mod=1e9+7;
LL c[N>>1][N>>1];
void init(){
  for(int i=0;i<=500;++i)c[i][0]=1;
  for(int i=1;i<=500;++i)
    for(int j=1;j<=500;++j)
      c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
char s[N];
int a[26];
int main(){
    init();
    int T;
    scanf("%d",&T);
    while(T--){
      scanf("%s",s+1);
      int l=strlen(s+1);
      for(int i=0;i<26;++i)a[i]=0;
      for(int i=1;i<=l;++i)
        a[s[i]-'a']++;
      int cnt=0,x;
      for(int i=0;i<26;++i)
      if(a[i]%2)++cnt,x=i;
      if(cnt){
        if(l%2){
           if(cnt>1){
            printf("0\n");
            continue;
           }
           else --a[x];
        }
        else{
           printf("0\n");
           continue;
        }
      }
      else{
        if(l%2){
           printf("0\n");
           continue;
        }
      }
      LL ans=1;
      l>>=1;
      for(int i=0;i<26;++i){
         if(!a[i])continue;
         a[i]>>=1;
         ans=(ans*c[l][a[i]])%mod;
         l-=a[i];
      }   
      printf("%I64d\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2016-03-26 22:02  shuguangzw  阅读(205)  评论(0编辑  收藏  举报