【原创】Codeforces 39A C*++ Calculations

Codeforces 39A C*++ Calculations

题意翻译

表达式求和,和正常的运算不同的是可以选择每个加数的运算顺序,求最大的值是多少。

题目描述

C*++ language is quite similar to C++. The similarity manifests itself in the fact that the programs written in C*++ sometimes behave unpredictably and lead to absolutely unexpected effects. For example, let’s imagine an arithmetic expression in C*++ that looks like this ( expression expression is the main term):

e x p r e s s i o n   : =   s u m m a n d   ∣   e x p r e s s i o n + s u m m a n d   ∣   e x p r e s s i o n − s u m m a n d expression~:=~ summand~|~ expression+summand ~|~ expression-summand expression := summand  expression+summand  expressionsummand
s u m m a n d   : =   i n c r e m e n t   ∣   c o e f f i c i e n t   ∗   i n c r e m e n t summand~:=~increment ~|~ coefficient~ *~ increment summand := increment  coefficient  increment
i n c r e m e n t   : =   a + +   ∣ + + a increment~:=~a++~|++a increment := a++ ++a
c o e f f i c i e n t   : =   0 ∣ 1 ∣ 2 ∣ . . . ∣ 1000 coefficient~:=~0|1|2|...|1000 coefficient := 012...1000
For example,"5*a++-3*++a+a++" is a valid expression in C*++.

Thus, we have a sum consisting of several summands divided by signs “+” or “-”. Every summand is an expression “a++” or “++a” multiplied by some integer coefficient. If the coefficient is omitted, it is suggested being equal to 1 1 1 .

The calculation of such sum in C*++ goes the following way. First all the summands are calculated one after another, then they are summed by the usual arithmetic rules. If the summand contains “a++”, then during the calculation first the value of the “a” variable is multiplied by the coefficient, then value of “a” is increased by 1 1 1 . If the summand contains “++a”, then the actions on it are performed in the reverse order: first “a” is increased by 1 1 1 , then — multiplied by the coefficient.

The summands may be calculated in any order, that’s why sometimes the result of the calculation is completely unpredictable! Your task is to find its largest possible value.

输入格式

The first input line contains an integer a a a ( − 1000 &lt; = a &lt; = 1000 -1000&lt;=a&lt;=1000 1000<=a<=1000 ) — the initial value of the variable “a”. The next line contains an expression in C*++ language of the described type. The number of the summands in the expression does not exceed 1000 1000 1000. It is guaranteed that the line describing the expression contains no spaces and tabulation.

输出格式

Output a single number — the maximal possible value of the expression.

输入输出样例

输入 #1

1
5*a++-3*++a+a++

输出 #1

11

输入 #2

3
a+++++a

输出 #2

8

说明/提示

Consider the second example. Initially a = 3 a=3 a=3 . Suppose that at first the first summand is calculated, and then the second one is. The first summand gets equal to 3 3 3 , and the value of a a is increased by 1 1 1 . At the calculation of the second summand a a a is increased once more (gets equal to 5 5 5 ). The value of the second summand is 5 5 5 , and together they give 8 8 8 . If we calculate the second summand first and the first summand later, then the both summands equals to 4 4 4 , and the result is 8 8 8, too.

题意

给定一个形如: p 1 ∗ ( + + a ) + p 2 ∗ ( a + + ) − p 3 ∗ ( + + a ) ⋯ + p k ∗ ( + + a ) p_1*(++a)+p_2*(a++)-p_3*(++a)\cdots +p_k*(++a) p1(++a)+p2(a++)p3(++a)+pk(++a)的运算式,a是变量, p i p_i pi是若干个正整数,加和减号是给定的,++a和a++是给定的,你可以自行决定计算这些a++和++a的顺序,给定a的初值,使运算式的结果最大。

分析

我起了,一眼秒了,又怀疑自己了, W D N M D \xcancel{W^D{N_M}^D} WDNMD 真就白给啊。

因为a只会不断变大,所以贪心地想,就让小的a乘上小的系数。也就是,把所有的系数拿出来排序(如果是减号就看作+负系数),然后再乘起来加起来就好了。

①如果a是负的,是不是在考虑负系数的时候……?
你在想什么?
系数是从小到大的,a也是从小到大的,也就是说绝对值越大的负系数和绝对值越大的-a会乘在一起,答案就更大了啊。

如果你实在是担心a负数的情况,你就这么意会一下,a+=1000,不就正了吗,再进行上述操作,最后在把刚开始加上的再减去,就不存在a是负数的问题了。
我就是这么把自己糊弄过去的。

②正确性?会不会存在k*(++a)>m*(a++) & k<m的情况?

就拿k*(++a)&m*(a++)来举例吧。
假设先算前者,ans=k*(a+1)+m*(a+1)=a*(k+m)+k+m
假设先算后者,ans=k*(a+2)+m*(a)=a*(k+m)+2*k
假设前者更优,那么就应有:[a*(k+m)+k+m]-[a*(k+m)+2*k]>0m-k>0;所以得出结论,系数更小的就要先算。
k*(++a)&m*(++a)k*(a++)&m*(a++)k*(a++)&m*(++a)的情况同理。

③读入比较烦,细节很多。

④对于同一个系数,是先计算++a还是a++?
你在想什么?把系数提出来之后k*[(a++)+(++a)+…]的结果会随着你顺序的改变而改变吗?

白给白给。

码代码的时候遇到的错误:
①读入优化没有读负数;
②考虑是++a还是a++的时候想着只看前两位是不是都是+号就好了,结果会被这样卡掉:a+++a++。还好我没花多久就想出这组数据了:a+++a+++++a

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN=102030;

void Read(int &p)//无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄无駄
{
	p=0;
	char c=getchar();
	while(c<'0' || c>'9') c=getchar();
	while(c>='0'  && c<='9') 
		p=p*10+c-'0',c=getchar();
}

char s[MAXN];
int n,ori,len,ans;
struct crl
{
	int num,pre;
	bool operator < (const crl &c) const
	{
		return num<c.num;
	}
}arr[MAXN];

int main() 
{
	for(int i=1;i<=100000;i++) arr[i].num=-1;
	scanf("%d",&ori),scanf("%s",s+1),len=strlen(s+1),s[0]='+';
	for(int i=1,las=0;i<=len;i++)
		if(s[i]=='a')
		{
			n++;
			for(int j=las+1;j<i;j++)
				if(s[j]>='0' && s[j]<='9') arr[n].num=(arr[n].num==-1?0:arr[n].num*10)+s[j]-'0';
				else break;
			if(arr[n].num==-1) arr[n].num=1; 
			arr[n].num*=(s[las]=='+'?1:-1),las=i+3-2*(arr[n].pre=s[i-1]==s[i-2] && s[i-2]=='+' && i-2>las);
		}
	sort(arr+1,arr+1+n);
	for(int i=1;i<=n;i++) if(arr[i].pre) ans+=++ori*arr[i].num; else ans+=ori++*arr[i].num;
	printf("%d\n",ans);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值