HDU 4726 Kia's Calculation

本文详细介绍了 HDU4726 Kia's Calculation 的解题思路和实现代码。该题要求对两个长度相同的整数进行位重组,并以一种特殊的加法方式计算最大可能的和。文章通过分析题目特点,采用贪心算法,降低了循环次数,从而避免了超时问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HDU 4726 Kia's Calculation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2436    Accepted Submission(s): 501

Problem 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 106, 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

 

 

 

【思路分析】

题意是给你两个长度相同且位数不超过106的整数,你需要分别先对这两个数进行数位之间的交换,但是交换后的数不能有前导零,然后你把这两个数按位相加(再余10),求这些情况中得到的最大的数。

一开始以为这两个数字的大小不超过106,错了很多次,最后注意到which is no larger than 106  ,这个is对应的是number of digits。。。。。。

要求满足题意的最大值,必定会涉及到两层for循环,若是直接对两个数a,b进行操作,则肯定会超时,但是改为对0—9这十个数字进行操作(若这个数字不存在a或b中则continue)就可以大大降低循环次数。求值的时候用到贪心的思想,即不断寻找当前数字和的最大值,但我个人觉得这个题目核心的地方还是在降低循环次数的操作上。


代码如下

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 1000010;
int first[15],second[15];
char s1[maxn],s2[maxn],ans[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    for(int i = 1;i <= t;i++)
    {
        scanf("%s %s",s1,s2);
        printf("Case #%d: ",i);

        int len = strlen(s1);
        memset(first,0,sizeof(first));
        memset(second,0,sizeof(second));

        if(strcmp(s1,"0") == 0)
        {
            printf("%s\n",s2);
            continue;
        }
        if(strcmp(s2,"0") == 0)
        {
            printf("%s\n",s1);
            continue;
        }

        for(int j = 0;j < len;j++)//记录每个数字出现的次数
        {
            first[s1[j] - '0']++;
            second[s2[j] - '0']++;
        }

        int num = 0,Max = -1,a,b;
        for(int j = 1;j <= 9;j++)//找第一个数字(注意不能有前导零,所以j初值为1)
        {
            if(first[j] == 0)//j这个数字不存在
                continue;
            for(int k = 1;k <= 9;k++)
            {
                if(second[k] == 0)
                    continue;
                int temp = (j + k) % 10;
                if(temp > Max)
                {
                    Max = temp;
                    a = j;
                    b = k;
                }
            }
        }

        ans[++num] = Max + '0';
        first[a]--;
        second[b]--;//取出后自减1

        while(num < len)//找第二个及之后的数字
        {
            Max = -1;
            for(int j = 0;j <= 9;j++)
            {
                if(first[j] == 0)
                    continue;
                for(int k = 0;k <= 9;k++)
                {
                    if(second[k] == 0)
                        continue;
                    int temp = (j + k) % 10;
                    if(temp > Max)
                    {
                        Max = temp;
                        a = j;
                        b = k;
                    }
                }
            }

            ans[++num] = Max + '0';
            first[a]--;
            second[b]--;
        }

        int j;
        for(j = 1;j <= len;j++)
        {
            if(ans[j] != '0')//忽视前导零
                break;
        }
        if(j == len + 1)
            printf("0\n");//结果的数位全为0情况直接输出零
        else
        {
            for(;j <= len;j++)
            {
                printf("%c",ans[j]);
            }
            printf("\n");
        }

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值