【数学】hdoj 5651 xiaoxin juju needs help (排列组合)

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 
#include 
#include 
#include 
#include 
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;
}

你可能感兴趣的:(数论)