HDU 5651 xiaoxin juju needs help 组合数

由于错过了bc的registering只能在这里发发题解了。。

给定一个字符串可自由打乱字母顺序,求能组成的回文串个数。
首先回文串对称的,所以只考虑一半就好了。
然后如果有多个字母出现奇数次那肯定答案为0。
再然只有一个有奇数次就拿一个放中间即可。
最后答案就是

n2!pa!pb!pz!

其中 px 表示字母x的出现次数除以2。

我才不会说因为最终答案忘模WA了次。。。

竟然有人问28行啥意思。。自己Google费马小定理。。

#include 
#include 
#define rep(i,j,k) for(i=j;i
typedef long long ll;
const ll mod = 1000000007;
int p[26]; ll a[1001];
char str[1005];
ll quick_pow(ll a, ll b) {
    ll ans = 1;
    for (; b; b /= 2, a = (a * a) % mod)
        if (b & 1) ans = (ans * a) % mod;
    return ans;
}
int main() {
    int t, i, n, odd;
    a[0] = 1;
    rep(i,1,1001) a[i] = (a[i - 1] * i) % mod;
    scanf("%d", &t);
    while (t--) {
        memset(p, 0, sizeof p);
        scanf("%s", str);
        n = strlen(str); odd = -1;
        rep(i,0,n) ++p[str[i] - 'a'];
        ll ans = a[n / 2];
        rep(i,0,26) if (p[i] & 1)
            if (odd == -1) odd = i;
            else { ans = 0; goto end; }
        rep(i,0,26) ans = (ans * quick_pow(a[p[i] / 2], mod - 2)) % mod;
        end: printf("%lld\n", ans);
    }
    return 0;
}

xiaoxin juju needs help

Accepts: 150 Submissions: 966
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

问题描述

xiaoxin巨从小就喜欢字符串,六年级的时候他就知道了什么是回文串。这时,xiaoxin巨说到:如果一个字符串 SS 是回文串,那么该字符串从前往后看和从后往前看是一样一样的。

六年级的暑假,xiaoxin很快就做完了暑假作业,然后到腾讯做起了实习生。这日,leader给了xiaoxin一个字符串,请xiaoxin帮忙写一个函数来生成所有可能的回文串,可以任意改变字符串的顺序但是不可以扔掉某个字符。并且leader告诉xiaoxin,每生成一个不一样的回文串就可以得到一颗西瓜糖。

请你帮忙计算xiaoxin的leader最多需要买多少颗西瓜糖呢?

输入描述

多组测试数据。第一行包含一个整数 T(T\leq 20)T(T≤20) 表示组数。每组测试数据给出一个只包含小写字母的字符串 S(1\leq length(S)\leq 1,000)S(1≤length(S)≤1,000)

输出描述

对于每组测试数据,输出一个数, 表示leader需要买的西瓜糖的个数,结果对 1,000,000,007 取模。

输入样例

3
aa
aabb
a

输出样例

1
2
1

你可能感兴趣的:(HDU,计数问题)