请你帮忙计算xiaoxin的leader最多需要买多少颗西瓜糖呢
分析:回文串,只可能有一个字母的个数为奇数,所以有两个及两个以上的奇数个字母的情况直接输出0。先统计各个字母的个数,然后只需要求解一般的个数就行了,因为另一半是对称的。所以要算出每个字母个数一半的不想异的全排列就好了;求解的时候要求到除法取模问题,只需求解除数的逆元。
不想异的全排列公式 一共有n个数,k种,每种ni个球求全排列个数
逆元的求解方法 :求解n对于m的逆元只需求(n*x)%m=1。用扩展欧几里得来求解
扩展欧几里得算法如下:http://blog.csdn.net/qq_27599517/article/details/50888092
代码如下:
#include <set> #include <map> #include <stack> #include <queue> #include <math.h> #include <vector> #include <string> #include <utility> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <functional> using namespace std; long long gcd(long long a,long long mod,long long& x, long long& y){ if(!mod){ x=1; y=0; return a; } long long ans=gcd(mod,a%mod,x,y); long long t=x; x=y; y=t-a/mod*y; return ans; }//求解逆元 const long long mod=1000000007; long long a[30]; long long su(long long sum){ long long ans=1; for(long long i=2;i<=sum;i++) ans=ans*i%mod; return ans; }//求解sum的阶乘 int main(){ long long t; scanf("%I64d",&t); while(t--){ memset(a,0,sizeof(a)); char s[1050]; scanf("%s",s); long long len=strlen(s); for(long long i=0;i<len;i++){ a[s[i]-'a']++; } long long flag=0; for(long long i=0;i<26;i++){ if(a[i]&1)flag++; } if(flag>1){ puts("0"); continue; } long long sum=0; long long x,y; for(long long i=0;i<26;i++){ a[i]/=2; sum+=a[i]; if(a[i]!=0){ a[i]=su(a[i]); gcd(a[i],mod,x,y); if(x<0)x+=mod; a[i]=x; } } long long ans=1; for(long long i=2;i<=sum;i++) ans=ans*i%mod; for(long long i=0;i<26;i++){ if(a[i]!=0) ans=ans*a[i]%mod; } printf("%I64d\n",ans%mod); } return 0; }