- 给你n个字母,求可以组成的回文串的个数
- 1.n为奇数,有一个字母的个数为奇数
- 2.n为偶数,字母个数全为偶数
- 然后将字母的个数num[i]/2,得出在对称轴左边的个项字母的个数
- 假设左边有len个字母,如果每个字母都不同则有len!中可能
- 然后除去所有重复的可能num[i]!即可
- 因为除法取模 (len!/num[i]!)%mod
- a^(p-1) = 1(mod p)p为素数 于是 a*a^(p-2) = 1(mod p)所以a^(p-2)替代1/a.
- 所以上面的公式 -> len!*(num[i]!)^(p-2)%mod
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #define mod 1000000007 using namespace std; typedef long long LL; int C[550][550]; int main() { memset(C,0,sizeof(C)); for(int i=0;i<=505;i++) { C[i][1]=i; C[i][0]=1; } for(int i=2;i<=500;i++) for(int j=2;j<=i;j++) { C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; } //freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t--) { LL ans=1; int i,len,cnt=0; char s[1050]; scanf("%s",s); len=strlen(s); int a[400],b[400],j=0; memset(a,0,sizeof(a)); for(i=0;i<len;i++) { a[s[i]]++; } for(i=‘a‘;i<=‘z‘;i++) { if(a[i]) { b[j++]=a[i]/2; } if(a[i]%2!=0) cnt++;//奇数个字符的个数 } if(cnt>1) { printf("0\n"); continue; } int h=len/2; for(i=0;i<j;i++) { ans=(ans*C[h][b[i]])%mod; h-=b[i]; } printf("%I64d\n",ans); } return 0; }
时间: 2024-10-01 03:22:42