xiaoxin juju needs help
Accepts: 150
Submissions: 966
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
xiaoxin巨从小就喜欢字符串,六年级的时候他就知道了什么是回文串。这时,xiaoxin巨说到:如果一个字符串 S 是回文串,那么该字符串从前往后看和从后往前看是一样一样的。
六年级的暑假,xiaoxin很快就做完了暑假作业,然后到腾讯做起了实习生。这日,leader给了xiaoxin一个字符串,请xiaoxin帮忙写一个函数来生成所有可能的回文串,可以任意改变字符串的顺序但是不可以扔掉某个字符。并且leader告诉xiaoxin,每生成一个不一样的回文串就可以得到一颗西瓜糖。
请你帮忙计算xiaoxin的leader最多需要买多少颗西瓜糖呢?
输入描述
多组测试数据。第一行包含一个整数 T(T≤20) 表示组数。每组测试数据给出一个只包含小写字母的字符串 S(1≤length(S)≤1,000)
输出描述
对于每组测试数据,输出一个数, 表示leader需要买的西瓜糖的个数,结果对 1,000,000,007 取模。
输入样例
3 aa aabb a
输出样例
1 2 1
/* 5651 xiaoxin juju needs help(逆元) 给你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 hhh-2016-03-26 21:45:56 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <functional> using namespace std; #define lson (i<<1) #define rson ((i<<1)|1) typedef long long ll; const int maxn = 20050; const int mod = 1e9+7; int a[maxn]; char Ma[maxn]; int Mp[maxn]; int num[26]; ll pow_mod(ll a,ll n) { ll t = 1; while(n) { if(n & 1) t = t*a%mod; a = a*a%mod; n >>= 1; } return t; } ll cal(int t) { ll ans = 1; for(int i =1;i <= num[t];i++) { ans = ans*i%mod; } return pow_mod(ans%mod,mod-2); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",Ma); int sum = 0; int len = strlen(Ma); memset(num,0,sizeof(num)); for(int i = 0; i < len; i++) { Mp[i] = Ma[i]-'a'; if(num[Mp[i]] == 0) sum ++; num[Mp[i]]++; } int flag = 0; int t; for(int i = 0; i < 26; i++) { if(num[i]%2) { flag ++; t = num[i]; } } if((len%2 && !flag) || (len%2==0 && flag) || (flag > 2)) printf("0 "); else if(len == 1) printf("1 "); else { ll ans = 1; for(int i =1;i <= len/2;i++) ans = ans*i%mod; for(int i = 0;i < 26;i++) { if(num[i]) { num[i] /= 2; ans = ans*cal(i)%mod; } } printf("%I64d ",ans); } } return 0; }