回文字符串<交流>--英雄会

回文字符串是指从左到右和从右到左相同的字符串,现给定一个仅由小写字母组成的字符串,你可以把它的字母重新排列,以形成不同的回文字符串。 输入:非空仅由小写字母组成的字符串,长度不超过100;

输出:能组成的所有回文串的个数(因为结果可能非常大,输出对1000000007取余数的结果)。

例如:输入"aabb" 输出为2(因为“aabb”对应的所有回文字符串有2个:abba和baab)

又是结果对1000000007取余的,看到这个我就感觉大数据会出现了,结果我果断没过,查了一下网友的给的测试案例:

s=“zsmjajrycysuqjvyyraqvoyggmjgsuiyvclurvmygoivmsurgxsyyblvbgxsszlsly”

结果是493584849

 我的是:

下面说一下我的思想,希望各位指点一下:

这题目很明显是个集合的问题,为了组成回文字符串必定会对称,若是奇数个字符,则中间随意,即字符中会有一个是单独的,若是偶数个字符,则每个字符都必须是偶数的。

所以total = length / 2;

总数的阶乘 / 每个字母出现的个数的阶乘<除以2以后的>

若是直接用 50! / X1! /X2!...这是肯定会超限的,所以这时候引用一个%1000000007;

我是将total!一点一点来的,然后同时也不断的进行/num,不过可能是因为中间%1000000007,一不小心弄出尴尬的数,后面/num强制转换了<个人认为的,正在研究,各位帮忙一下>;

 

贴出我的代码吧,希望各位给点建议:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>

using namespace std;

int palindrome(const string &s){

    long long int result = 1;
    int totalLen = 0;
    int countOdd = 0;  //奇数字母的个数,超过两个回文的即为0个
    int count[26] = {0};

    for (int i = 0; s[i] != '\0'; i++)  //统计各个字母出现的个数
    {
        count[s[i]-'a']++;
    }

    for (int i = 0; i < 26; i++)
    {
       if (count[i] % 2 == 1)
       {
           countOdd++;
       }
       count[i] /= 2; //将字母的出现次数为一半,只需考虑一半的字符串,因为是回文!
    }

    if (countOdd > 1)
    {
        return 0;  //超过两次以上的奇数个字母
    }

    for (int i = 0; i < 26; i++)  //集合
    {
        if (count[i] == 1)  //出现一次直接算集合即可
        {
            totalLen++;
            result = result * totalLen;
            result %= 1000000007;
        }

        else if (count[i] > 1)  //出现两次及以上需要除去count[i]!<阶乘>
        {
            int num = 1;
            while (count[i]--)
            {
                totalLen++;  //记录长度
                result = result * totalLen / num ;  //结果  //将字母的发生次数相除即/count[i]!

                result %= 1000000007;
                num++;  //每个字母发生次数
            }
        }
        else ;
    }

    return result;
}

//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{
    cout<<palindrome("hqaymehhrsfuqrpahrimsxftuxqrpsejouuehaqtsryxjhearxmogmi");
    return 0;
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。


 我的偶然对了...

路过的大神给点建议吧,谢谢了啊o(∩_∩)o

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值