2020牛客寒假算法基础集训营4 E 最小表达式

https://ac.nowcoder.com/acm/contest/3005/E

题目描述

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

合法的表达式的定义如下:

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

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

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

思路

 最小的表达式值,如果有n个加号,就是n+1部分,只有把这些数字平均分配到每一个位置,并且把小的数字放在高位,大的数字放低位,就可以保证总和最小。所以先排序,加号字符比数字小,在前面,找出多少个加号以及第一个数字的位置,然后将数字一次从小到大放到第1、2、3、···、n+1部分中去,最后求和就行了。

注意需要高精度加法

我发现char数组好烦,改了半天数组char*越界了,非法修改了值,wa了好久,还是用string过了

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
string add(string a, string b) {
	// lena > lenb
	string c;
	int lena = a.length();
	int lenb = b.length();
	int up = 0;
	int i, j;
	for (i = lena - 1, j = lenb - 1; i >= 0 && j >= 0; i--, j--) {
		int num = a[i] - '0' + b[j] - '0';
		num += up;
		c += (num % 10 + '0');
		up = num / 10;
	}
	for (; i >= 0; i--) {
		int num = a[i] - '0';
		num += up;
		c += (num % 10 + '0');
		up = num / 10;
	}
	while (up) {
		int num = up % 10;
		c += (num % 10 + '0');
		up /= 10;
	}
	reverse(c.begin(), c.end());
	return c;
}
string str;
string ans[N];
int main()
{
	ios::sync_with_stdio(0);
	cin >> str;
	sort(str.begin(), str.end());
	int len = str.length();
	int ind = -1;
	int cnt = 0;
	for (int i = 0; i < len; i++)if (str[i] == '+') ++cnt;
	++cnt;
	for (int i = 0; i < len; i++) {
		if (isdigit(str[i])) {
			ind = i;
			break;
		}
	}
	for (int i = ind, k = 0; i < len; i++, k++) {
		ans[k % cnt] += str[i];
	}
	string res = ans[0];
	for (int i = 1; i < cnt; i++) {
		res = add(res, ans[i]);
	}
	cout << res;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值