zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU 4726 Kia's Calculation( 贪心&&计数排序)

    Description
    Doctor Ghee is teaching Kia how to calculate the sum of two integers. But Kia is so careless and alway forget to carry a number when the sum of two digits exceeds 9. For example, when she calculates 4567+5789, she will get 9246, and for 1234+9876, she will get 0. Ghee is angry about this, and makes a hard problem for her to solve:
    Now Kia has two integers A and B, she can shuffle the digits in each number as she like, but leading zeros are not allowed. That is to say, for A = 11024, she can rearrange the number as 10124, or 41102, or many other, but 02411 is not allowed.
    After she shuffles A and B, she will add them together, in her own way. And what will be the maximum possible sum of A "+" B ?
     
    Input
    The rst line has a number T (T <= 25) , indicating the number of test cases.
    For each test case there are two lines. First line has the number A, and the second line has the number B.
    Both A and B will have same number of digits, which is no larger than 10 6, and without leading zeros.
     
    Output
    For test case X, output "Case #X: " first, then output the maximum possible sum without leading zeros.
     
    Sample Input
     1
    5958
    3036
     
    Sample Output
     Case #1: 8984


    题目要求是给定两个数,能加合成另一个数,要求这个数最大,然而第一位不能有0加合成。
    然而题目给的AB两个数长度达到10^6(一开始这个条件理解错了,以为是AB上界是10^6,然后果断暴力超时了)
    不过,虽然AB长度到达10^6,但是每一位毕竟是由0到9数字构成的,而且题目的加合运算是每位进行的。可以考虑统计0到9的个数然后进行贪心。
    由于考虑到第一位不能有0加合,对第一位加合情况进行枚举求最大的。
    然后就是对后面的位数进行贪心了:

    对于不超过10的情况,自然是从9开始贪心,然后8、7、6……
    而且由于对于加合成k的情况,每个能加合成k的对都是不同的,自然互不影响,所以对于每一个能加合成k的情况,就把所有的对全部用完,直到A组和B组中有一个减到0。

    对于需要模10的情况。如果同样是模10加合成k,那么肯定先考虑模10得到k的,才会去考虑不模得到k-1的,所以考虑完不模的情况就马上考虑模的情况。

    此外这题还有注意点,就是A和B中有一组只有0的情况或两组都是只有0的情况,需要特判。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    int a[15], b[15], ans[1000010];
    
    void Input()
    {
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        char ch;
        for (;;)
        {
            ch = getchar();
            if (ch == '
    ')
                break;
            a[ch-'0']++;
        }
        for (;;)
        {
            ch = getchar();
            if (ch == '
    ')
                break;
            b[ch-'0']++;
        }
    }
    
    void Work()
    {
        int cnt = 0, maxOne = -1, iOne, jOne;
        for (int i = 1; i < 10; ++i)
        {
            if (a[i] == 0)
                continue;
            for (int j = 1; j < 10; ++j)
            {
                if (b[j] == 0)
                    continue;
                if (maxOne < (i+j)%10)
                {
                    maxOne = (i+j)%10;
                    iOne = i;
                    jOne = j;
                }
            }
        }
        if (maxOne != -1)//第一位出现0加一个数的情况
        {
            ans[cnt] = maxOne;
            cnt++;
            a[iOne]--;
            b[jOne]--;
        }
    
        for (int k = 9; k >= 0; k--)
        {
            for (int i = k; i >= 0; --i)
            {
                while (a[i] && b[k-i])
                {
                    ans[cnt] = k;
                    cnt++;
                    a[i]--;
                    b[k-i]--;
                }
            }
            for (int i = k; i < 10; ++i)
            {
                while (a[i] && b[k+10-i])
                {
                    ans[cnt] = k;
                    cnt++;
                    a[i]--;
                    b[k+10-i]--;
                }
            }
        }
        int i = 0;
        while (ans[i] == 0 && i < cnt)//排除第一位出现0的情况
            i++;
        if (i == cnt)//所有位都是0的情况
        {
            printf("0
    ");
            return;
        }
        for (; i < cnt; ++i)
            printf("%d", ans[i]);
        printf("
    ");
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T;
        scanf("%d", &T);
        getchar();
        for (int times = 1; times <= T; ++times)
        {
            printf("Case #%d: ", times);
            Input();
            Work();
        }
        return 0;
    }
  • 相关阅读:
    Delphi如何处理在进行大量循环时,导致的应用程序没有响应的情况
    [转]:Delphi 中的哈希表(1): THashedStringList
    C# 计算两个字符串的相似度
    中文字号VS英文字号(磅)VS像素值
    在C#中如何将多个rtf文件内容组合在一起用一个rtf文件保存?
    C#中用RichTextBox实现图文混排和保存的例子
    ISE MAP报错: Unsupported programming for BSCAN block and JTAG_CHAIN attribute value 1的解决方法
    [转]matlab如何复制spectrum scope的图
    iMpACT中的Xilinx Prom烧录
    【verilog】fdisplay中如何保存有符号形式
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4541061.html
Copyright © 2011-2022 走看看