蓝桥杯 2019省赛 后缀表达式

蓝桥杯 2019省赛 后缀表达式

题目传送门

思路

完全错误的思路

用贪心的想法,加大的,减小的。然后发现WA了

正确思路

后缀表达式加括号

关于后缀表达式其实有个点是容易被忽略的(也是为什么上面暴力贪心忽略的一个要点):其实后缀表达式也是可以加括号的(为什么可以加括号?因为那道后缀表达式加括号进行计算的模拟题我没过

换句话说,中缀表达式中括号加上减号的一些骚操作是可以在后缀表达式中实现的

括号与减号

加法其实比较普通(毕竟加再多括号还是求个和),但是减法就有点特殊的性质了。

  • 如果将加法式子括起来,前面放个减号,那么里面的加号全变成减号了。
  • 如果括起来的是减号(或者负数),那么就变成加绝对值了。

基于这个性质,(其实还是贪心),就可以通过贪心将负数和减号尽量减到最少。

因此,如果没有减号的话,输出所有数字的和即可。

如果可以存在减号的话,那么就可以任意对数字进行加或者减

  • 如果存在负数的话,那么要尽量让负数转为正数,也就是把所有负数加个括号扩上即可。
  • 如果没有负数的话,根据之前的想法,多个负号其实可以削减为一个,也就是说多个负号可以减到1个。那么,按照贪心的思想,直接最大值减去最小值即可。

综合上面存在减号的情况,一开始让最大值减去最小值就行了。如果存在负数,那么负数也会被转为正数。如果没有存在负数,那么减去一个最小的正数也符合贪心思想。剩下的直接加上绝对值即可。

代码(C++)

一种可行的c++代码实现。

#include <bits/stdc++.h>
typedef long long ll;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    int n, m;
    std::cin >> n >> m;

    std::vector<ll>v(n + m + 1);
    for (int i = 0; i < v.size(); ++ i) 
        std::cin >> v[i];
    std::sort(v.begin(), v.end());

    ll ans = 0;
    if (m == 0) {
        for (int i = 0; i < v.size(); ++ i) {
            ans += v[i];
        }
    } else {
        ans = v.back() - v.front();
        for (int i = 1; i < v.size() - 1; ++ i) {
            ans += std::abs(v[i]);
        }
    }
    std::cout << ans << '\n';

    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值