hdoj 5651 xiaoxin juju needs help (排列组合)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5651
参考他人的博客:http://blog.csdn.net/wyg1997/article/details/50988460
此题英文题目有点坑吧,要不就是我英语太差,我是感觉它没有说明白。
我第一次题意理解错了,以为是子串为回文串的个数,打了代码直接WA。。。
题目大意:给你一串字符串,让你改变其位置,不能舍去任何字符,有多少回文串。
题目思路: 知道了题目的大意后,明显的,有三种情况。
1.输出0的情况。
2.字母中有一个数量为奇数,把其作为中心。
3.字母全为偶数。
进行排列组合!!!
自己求C函数用的是阶乘方法,后来看到其他人的博客代码,发现了一种简单点的方法(是个收获哈哈)。
改进后AC代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <iostream>
using namespace std;
#define INF 0x3f3f3f
#define MAXN 1001
#define mod 1000000007
#define ll __int64
char a[MAXN];
ll c[501][501];
void C()
{
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;
}
}
void solve()
{
int len = strlen(a);
int num[27];
memset(num,0,sizeof(num));
for(int i = 0; i < len; i++)
num[a[i]-'a'+1]++;
int odd = 0;
for(int i = 1; i < 27; i++)
{
if(num[i] & 1)
odd++;
num[i] = num[i]/2;
}
if(odd > 1)
{
printf("0\n");
return ;
}
len = len / 2;
ll ans = 1;
//cout << c[1][1] << endl;
for(int i = 1; i < 27; i++)
{
ans = (ans * c[len][num[i]]) % mod;
len -= num[i];
// cout << ans << " ";
}
printf("%lld\n",ans);
return ;
}
int main()
{
C();
int n;
scanf("%d",&n);
while(n--)
{
memset(a,0,sizeof(a));
scanf("%s",a);
solve();
}
return 0;
}