牛客网最小表达式E

最小表达式E

牛客网题目地址
描述:

给出一个包含数字1-9和加号的字符串,请你将字符串中的字符任意排列,但每种字符数目不变,使得结果是一个合法的表达式,而且表达式的值最小。输出那个最小表达式的值
合法的表达式的定义如下:

  • 一个数字,如233,是一个合法的表达式

  • A + B是合法的表达式,当且仅当 A , B 都是合法的表达式

保证给出的表达式经过重排,存在一个合法的解。

输入描述:
一行输入一个字符串,仅包含数字1-9和加号+。
字符串的长度小于5*10^5
输出描述:
一行输出一个数字,代表最小的解。
输入
23984692+238752+2+34+
输出
5461

/*
我们拥有的可以放数字的数位的权值分别是1,1,1,1,1,...,1,10,10,10,10,...,10,100,...
(每种各加号个数加一个),于是只需要贪心的将大的数字放到小权值的数位上即可。

考虑题目中的第四个样例:23984692+238752+2+34+
这个样例的数字排序后为['2', '2', '2', '2', '2', '3', '3', '3', '4', '4', '5', '6', '7', '8', '8', '9', '9'],
加号有四个,则意味着我们要建立五个数字。
每个数字从后向前添加数位,则先添加个位数,十位数,再添加百位数,等等等等。
并且我们一定是按照顺序添加,不可能在个位数尚有未填写的情况去填另一个数字的百位数,
因为不优。答案为
2369+2359+248+248+237=5461
*/ 
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
int cnt[20];
int sum[500050];
 
char s[500050];
int main() {
    cin>>s;//下面代码以23984692+238752+2+34+为例 
    int ccnt = 1;
    int n = strlen(s);
    for(int i=0;i<n;i++){
        if(isdigit(s[i])){//isdigit函数 若参数c为阿拉伯数字0~9,则返回非0值,否则返回0。
            cnt[s[i]-'0']+=1;//字符变整数   cnt[2]=5  cnt[3]=3  cnt[4]=2.... 表示有5个2,3个3,2个4 
        }else{
            ccnt+=1;//一共要有几位数   
        }
    }
    int p = 0,cp = 0;
    for(int i=10;i>=1;i--){
        while(cnt[i]){
            sum[cp]+=i;//位数相同的每一位的和  从低位算起  sum[0]=9+9+8+8+7=41 
            cnt[i]-=1;//个数少1 
            p = (p+1)%ccnt;//判断位数是否需要变成高位 
            if(p == 0)
				cp+=1;
        }
    }
    for(int i=0;i<500010;i++){//计算最小和 
        sum[i+1]+=sum[i]/10;//低位向高位进位  sum[1]=sum[1]+sum[0]/10  sum[1]=22+4=26
        sum[i]%=10;//第i位的值 sum[0]=sum[0]%10=41%10=1
    }
    int opt = 0;
    for(int i=500010;i>=0;i--){
        if(opt || sum[i]){
            cout<<sum[i];//输出各个位数上的值  sum[0]=1,所以最低位为1 
            opt = 1;
        }
    }
    cout<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值