zoukankan      html  css  js  c++  java
  • HDU 5651 xiaoxin juju needs help 逆元

    题目链接:

    hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5651

    bc:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=682&pid=1002

    xiaoxin juju needs help

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

    As we all known, xiaoxin is a brilliant coder. He knew palindromic strings when he was only a six grade student at elementry school.

    This summer he was working at Tencent as an intern. One day his leader came to ask xiaoxin for help. His leader gave him a string and he wanted xiaoxin to generate palindromic strings for him. Once xiaoxin generates a different palindromic string, his leader will give him a watermelon candy. The problem is how many candies xiaoxin's leader needs to buy?

    Input

    This problem has multi test cases. First line contains a single integer T(Tleq 20)T(T20) which represents the number of test cases. For each test case, there is a single line containing a string S(1 leq length(S) leq 1,000)S(1length(S)1,000).

    Output

    For each test case, print an integer which is the number of watermelon candies xiaoxin's leader needs to buy after mod 1,000,000,0071,000,000,007.

    Sample Input
    3
    aa
    aabb
    a
    Sample Output
    1
    2
    1

    题解:

    1、可行性:

    统计每个字母出去的次数,如果有两种即以上字母出现的次数为奇数,则一定不可能排出回文串。

    2、统计:

    由于回文串左右两边必须相同,所以我们考虑一边就可以了(如果为奇数则正中间一个不管就和偶数情况是一样的了)。

    则可以转化为排列组合问题,等价于求解: (cnt[i]代表某个字母出现的次数(cnt[i]>0) )

    ( )%(1e9+7)

    由于涉及到除法,要求逆元:

    例子:

      求a/b(mod n) 如果b与n互质,则求满足bx=1(%n)的一个解x,原式可转化为a/b*bx(%n),即a*x(%n);这样就把除法消除了。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    const int maxn = 1000 + 10;
    const int mod = 1e9 + 7;
    typedef long long LL;
    
    char str[maxn];
    int n;
    
    int cnt[33];
    int tmp[33], tot;
    
    LL b[maxn];
    //预处理出阶乘
    void pre() {
        b[0] = b[1] = 1;
        for (int i = 2; i < maxn; i++) b[i] = (b[i - 1] * i) % mod;
    }
    //扩展的欧几里得算法求逆元
    void gcd(LL a, LL b, LL &d, LL &x, LL &y) {
        if (!b) {
            d = a;
            x = 1; y = 0;
        }
        else {
            gcd(b, a%b, d, y, x);//y=x',x=y';
            //x=y'; y=x'-(a/b)*y';
            y -= (a / b)*x;
        }
    }
    
    void init() {
        tot = 0;
        memset(cnt, 0, sizeof(cnt));
    }
    
    int main() {
        pre();
        int tc;
        scanf("%d", &tc);
        while (tc--) {
            init();
            scanf("%s", str);
            n = strlen(str);
            for (int i = 0; i < strlen(str); i++) {
                cnt[str[i] - 'a']++;
            }
            int flag = 0;
            for (int i = 0; i < 33; i++) {
                if (cnt[i] % 2) flag++;
                //统计一半的字母出现的次数
                if (cnt[i] > 0) {
                    tmp[tot++] = cnt[i] / 2;
                }
            }
            if (flag > 1) { printf("0
    "); continue; }
            LL sum = 1;
            for (int i = 0; i < tot; i++) {
                int t = tmp[i];
                sum = (sum*b[t]) % mod;
            }
            LL d, x, y;
            gcd(sum, mod, d, x, y);
            //x有可能是负数,需要处理成正的。
            x = (x%mod + mod) % mod;
            LL ans = (b[n / 2] * x) % mod;
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    求二叉树中最远两节点距离
    计算机系统
    webdriver高级应用- 无人工干预地自动下载某个文件
    webdriver高级应用- 改变一个页面对象的属性值
    webdriver高级应用- 在ajax方式产生的浮动框中,单击选择包含某个关键字的选项
    webdriver高级应用-js操作滚动条
    webdriver高级应用-使用JavaScript操作页面元素
    Selenium WebDriver- 指定页面加载时间
    Selenium WebDriver- 操作浏览器的cookie
    Selenium WebDriver- 操作JavaScript的prompt弹窗(使用率低)
  • 原文地址:https://www.cnblogs.com/fenice/p/5327342.html
Copyright © 2011-2022 走看看