2020牛客寒假算法基础集训营4
E题最小表达式
补题ing,简单的贪心+模拟啦
传送门
题目的大概意思是说给你一组字符串(只包含数字1-9和‘+’),可以打乱顺序,然后求表达式的最小值。
这道题的思路就是看看有几个加号,比如有2个加号,那我们就需要三个数字让他们组成合法的表达式。
我们先对输入的字符串进行处理,统计一下每个数字的个数和加号的个数
贪心策略:我们要组成最小的表达式,就需要让当前最大的数字放在最低位,比如91+82这个表达式,我们要把数字9和数字8放在个位(最低位),当然这个地方是要根据有多少个‘+’来决定的,我们当然希望把所有的数字都放在个位,但是‘+’不允许呀!!!
我们组成的表达式的数字的个数=‘+’的个数+1
因为题目要求的字符串可以达到5e5,所以我们就按照大数相加的方式处理呀~
所以我们先处理个位,处理‘+’的个数+1次,然后再处理十位,百位,千位等等
(赛后补题的时候wa了两次,因为我在输出的时候从最大的N开始的,但是我开的数组最大的就是N,数组越界了qaq)
长记性了,后来我把数组开大点就好啦
上代码啦~
#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 5e5 + 10;
string s;
int n;
int cnt[10];
int sum[N + 10];
int p, cp;
int ccnt = 1;
int main()
{
cin >> s;
n = s.size();
for (int i = 0; i < n; i++)
{
if (isdigit(s[i]))
{
cnt[s[i] - '0']++;
}
else
{
ccnt++;//这个记录加号的个数,最后得到的是操作数的个数
}
}
for (int i = 9; i >= 1; i--)
{
while (cnt[i])
{
sum[cp] += i;
cnt[i]--;
p = (p + 1) % ccnt;//这个是记录当前位数操作了多少个数,操作完了操作下个位
if (!p)
{
cp++;//这个是依次从个位,十位,百位等等
}
}
}
for (int i = 0; i < N; i++)
{
sum[i + 1] += sum[i] / 10;//这个是大数的进位
sum[i] %= 10;
}
int opt = 0;
for (int i = N; i >= 0; i--)
{
if (opt || sum[i])
{
opt = 1;
cout << sum[i];
}
}
cout << endl;
return 0;
}
结束啦~我们下次见