bestcoder #77 xiaoxin juju needs help

xiaoxin juju needs help

 
 Accepts: 134
 
 Submissions: 309
 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(T20) 表示组数。每组测试数据给出一个只包含小写字母的字符串 S(1\leq length(S)\leq 1,000)S(1length(S)1,000)
输出描述
对于每组测试数据,输出一个数, 表示leader需要买的西瓜糖的个数,结果对 1,000,000,0071,000,000,007 取模。
输入样例
3
aa
aabb
a
输出样例
1
2
1

思路:如果说有大于1个的奇数字符存在,那么就不能构成回文。能构成的情况下,判断一半边就行了,另一个半边相同就行。然后就是组合数形式

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#define ll __int64
#define MOD 1000000007
using namespace std;

char s[10009];
int num[1000];
//map<char,int>mp;

ll kuai(ll m,ll n)
{
    ll b=1LL;
    while(n)
    {
        if(n&1)
            b=b*m%MOD;
        n>>=1;
        m=m*m%MOD;
    }
    return b;
}
int main()
{
    int n;
    scanf("%d",&n);
        while(n--)
        {
            scanf("%s",s);
            int len=strlen(s);

            if(len==1)
            {
                puts("1");
                continue;
            }

           memset(num,0,sizeof num);

            for(int i=0;i<len;i++)
            {
                num[s[i]]++;
            }
            int flag=0;
            for(int i=0;i<256;i++)
            {
                if(num[i]%2) flag++;
            }
            if(flag>1)
            {
                puts("0");
                continue;
            }
            int sum=0;
            for(int i=0;i<256;i++)
            {
                num[i]/=2;
                sum+=num[i];
            }

            ll ans=1;
            for(int i=0;i<256;i++)
            {
                if(num[i] && sum>=num[i])
                {
                    ll tmp=1LL;
                    ll tmp2=1LL;
                    int t=min(sum-num[i],num[i]);
                    int fff=sum;
                    for(int j=1;j<=t;j++)
                    {
                         tmp=tmp*fff%MOD;
                         fff--;
                    }
                    for(int j=1;j<=t;j++)
                        tmp2=tmp2*j%MOD;

                    tmp=tmp*kuai(tmp2,MOD-2)%MOD;//逆元把除法转乘法

                    sum-=num[i];
                    ans=(ans*tmp)%MOD;
                }
            }

            printf("%I64d\n",ans);
        }
    return 0;
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值