题目描述
给出一个包含数字1-9和加号的字符串,请你将字符串中的字符任意排列,但每种字符数目不变,使得结果是一个合法的表达式,而且表达式的值最小。输出那个最小表达式的值
合法的表达式的定义如下:
- 一个数字,如233,是一个合法的表达式
- A + B是合法的表达式,当且仅当 A , B 都是合法的表达式
保证给出的表达式经过重排,存在一个合法的解。
输入描述:
一行输入一个字符串,仅包含数字1-9和加号+。
字符串的长度小于500000。
输出描述:
一行输出一个数字,代表最小的解。
示例1
输入
111+1
输出
22
说明
11+11=22
示例2
输入
23984692+238752+2+34+
输出
5461
说明
嗯,这个答案是可以得到的
备注:
注意,答案长度可能长达500000个字符。
这个题怎么说呢,其实是挺简单的一道题,统计一下有k个加号,不是加号的字符用一个数组a存起来,则一共分为k+1个数加起来的和,根据贪心的原则,大的数在后面,我刚开始想的是先对数组a进行排序,然后每个数的位置对k+1取模相等的数组成一个数,然后就能得到k个数,这样想其实是没问题的,但是这样写会爆掉。上一下我开始提交的代码
#include<bits/stdc++.h>
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
const int mod = 998244353;
const int MAXN = 1e6 + 10;
const int INF = 0x3f3f3f3f;
LL res=1,n,k,Max,now,m,sum=0,c;
string st[MAXN];
int a[MAXN];
int main()
{
string str;
cin>>str;
int len=str.size();
for(int i=0;i<str.size();i++)
{
if(str[i]=='+')k++;
else a[now++]=str[i]-'0';
}
sort(a,a+now);
for(int i=0;i<=k;i++)
{
res=0;
for(int j=i;j<now;j+=(k+1))
{
res=res*10+(a[j]);
}
//cout<<res<<endl;
sum+=res;
}
cout<<sum<<endl;
}
明显这里必须的用数组存,后来想想发现,是把每一位上的和加起来,存到数组里,有进位的话要进位,哎,自己真的太菜了!
AC代码
#include<bits/stdc++.h>
#define N 1010000
#define MS0(X) memset((X), 0, sizeof((X)))
typedef long long ll;
typedef unsigned long long ull;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
using namespace std;
int a[N],b[N],jw,arr[N],h;
char s[N];
int now,k;
int main()
{
string str;
cin>>str;
for(int i=0;i<str.size();i++)
{
if(str[i]=='+')k++;//统计等号个数,分成k+1个数
else s[now++]=str[i];
}
sort(s,s+now);
for(int i=now-1;i>=0;i=i-k-1)
{
int ans=0;
for(int j=i;j>=i-k&&j>=0;j--)
ans=ans+s[j]-'0';//对每一位上的数进行相加
ans+=jw;//当前位的数需要加上来自前一位的进位
arr[h++]=ans%10;//当前位的数位ans对10取模
jw=ans/10;、、向下一位进位
}
if(jw>0)arr[h++]=jw;//进位
for(int i=h-1;i>=0;i--)//倒着输出
cout<<arr[i];
cout<<endl;
}
感谢爸爸们的访问,你们的访问时我不断进步的动力!