As we all known, xiaoxin is a brilliant coder. He knew palindromic strings when he was only a six grade student at elementry school.
This summer he was working at Tencent as an intern. One day his leader came to ask xiaoxin for help. His leader gave him a string and he wanted xiaoxin to generate palindromic strings for him. Once xiaoxin generates a different palindromic string, his leader will give him a watermelon candy. The problem is how many candies xiaoxin’s leader needs to buy?
Input
This problem has multi test cases. First line contains a single integer T(T≤20)T(T≤20) which represents the number of test cases.
For each test case, there is a single line containing a string S(1≤length(S)≤1,000)S(1≤length(S)≤1,000).
Output
For each test case, print an integer which is the number of watermelon candies xiaoxin’s leader needs to buy after mod 1,000,000,0071,000,000,007.
Sample Input
3
aa
aabb
a
Sample Output
1
2
1
此题 应用 组合数 排列 中 带有重复的 字符串的 全排列 问题
for example :
有 你个 小球 其中 m 个 小球 是相同的 , 那么 这 n 个小球 的 全排列 为 !n / !m ;
整体思路 先用 一个 整形数组 和 map 将字符串里 的 不同的字符 进行编号 ,数组 用来储存 相同编号 所对应 的字符 的 个数 , 数组 的下标 即 对应 字符 的编号, 然后 分 总字符数 的 奇 和 偶 分别 考虑
先判断 该字符串 是否满足 可以组成回文串 的 条件 (奇 与 偶 的判断条件 不同 ) 然后进行 公式 计算 其中 还采用了 乘法逆元 防止 被除数 过大 导致 精度损失 太大 ;
详细 见代码
代码如下 :
#include <cstring>
#include <algorithm>
#include <map>
#define mod 1000000007
#define LL long long
using namespace std;
LL pows[600];
void F()
{
pows[0] = 1;
LL num = 1;
for(int i = 1; i < 510; i++)
{
num *= i;
num %= mod;
pows[i] = num;
}
}
LL quick_pows(LL a, LL b)
{
LL ret = 1;
LL temp = a;
while(b)
{
if(b & 1) ret = ret * temp % mod;
temp = temp * temp % mod;
b /= 2;
}
return ret;
}
int main()
{
F();
int t;
scanf("%d", &t);
getchar();// 去空格
while(t--)
{
int len;
int arr[1010];// 存储 字符串
char str[1010];// 存储 字符出现的次数
map<char, int> sky;
gets(str);
len = strlen(str);
sky.clear();
memset(arr, 0, sizeof(arr));
int num = 1;// 为 字符 编号
for(int i = 0; i < len; i++)
{
char ch = str[i];
if(!sky[ch])// 如果 该字符没有出现过
{
sky[ch] = num++;// 则对该字符 编号
arr[sky[ch]]++;
}
else
arr[sky[ch]]++;
}
int kind, group = 0; // group 存储 字符 对 的 对数
kind = num - 1;// 字符 的种类 数
for(int i = 1; i <= kind; i++)
group += arr[i]/2;
LL a, b = 1, ans;
if(len % 2 == 0)
{
if(group*2 != len) printf("0\n");
else
{
for(int i = 1; i <= kind; i++)
{
b *= pows[arr[i] / 2];
b %= mod;
}
a = pows[group];
ans = a * quick_pows(b, mod-2) % mod;// 采用 乘法逆元 将a/ b % mod => a*(b关于 mod 的逆元)% mod
printf("%lld\n", ans);
}
}
else
{
if(group*2 != len-1) printf("0\n");
else
{
for(int i = 1; i <= kind; i++)
{
b *= pows[arr[i]/2];
b %= mod;
}
a = pows[group];
ans = a * quick_pows(b, mod-2) % mod;
printf("%lld\n", ans);
}
}
}
return 0;
}