• 寒假Day28:[蓝桥杯2019初赛]后缀表达式+修改数组


     [蓝桥杯2019初赛]后缀表达式

    题目链接:http://oj.ecustacm.cn/problem.php?id=1467

    题目描述

    给定N 个加号、M 个减号以及N + M + 1 个整数A1,A2,...,AN+M+1
    小明想知道在所有由这N 个加号、M 个减号以及N + M +1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个?
    请你输出这个最大的结果。
    例如使用1 2 3 + -,则“2 3 + 1 -” 这个后缀表达式结果是4,是最大的。

    输入

    第一行包含两个整数N 和M。
    第二行包含N + M + 1 个整数A1,A2,...,AN+M+1
    0<=N,M<=100000,-10^9<=Ai<=10^9

    输出

    输出一个整数,代表答案。

    样例输入 Copy

    1 1
    1 2 3

    样例输出 Copy

    4

    https://blog.csdn.net/ryo_218/article/details/89515960

    https://blog.csdn.net/weixin_42765557/article/details/88914230

    思路可以看一下上面两个博客,这俩博客的代码也存在问题,

    由于我的代码没过完所有数据,暂不放思路。

    网上的代码貌似都不对,无法过完全部数据,

    我的代码(没有AC,待解决):

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<map>
     5 using namespace std;
     6 const int N=100020;
     7 typedef long long ll;
     8 
     9 ll a[N],z[N],f[N];
    10 
    11 bool cmp1(ll x,ll y)
    12 {
    13     return x>y;
    14 }
    15 
    16 int main()
    17 {
    18     ll n,m,sum=0,sum1=0,sum2=0;
    19     cin>>n>>m;
    20     int p=0,q=0;
    21     for(int i=0; i<n+m+1; i++)
    22     {
    23         cin>>a[i];
    24         sum+=a[i];
    25         if(a[i]>=0)
    26             z[p++]=a[i],sum1+=a[i];
    27         else
    28             f[q++]=a[i],sum2+=a[i];
    29     }
    30 //    if(n==0)
    31 //        cout<<(-1)*sum<<endl;
    32     if(m==0)
    33         cout<<sum<<endl;
    34     else
    35     {
    36         sum=0;
    37         sort(z,z+p);
    38         sort(f,f+q);
    39         if(m==q)
    40             sum=sum1+(-1)*sum2;
    41         else if(m<q)//负数比负号多
    42         {
    43             sum=0;
    44             ll ss=0;
    45             int s=1;
    46             for(int i=0;i<q;i++)
    47             {
    48                 if(s<m)
    49                 sum=sum+(-1)*f[i],s++;
    50                 else
    51                     ss+=f[i];
    52             }
    53             sum=sum+(-1)*ss+sum1;
    54 //            int s=0;
    55 //            for(int i=0;i<q;i++)
    56 //            {
    57 //                if(s<m)
    58 //                    sum-=f[i],s++;
    59 //                else
    60 //                    sum+=f[i];
    61 //            }
    62 //            sum+=sum1;
    63         }
    64         else if(m>q)//负号比负数多
    65         {
    66             int s=m-q;
    67             for(int i=0; i<p; i++)
    68             {
    69                 if(s)
    70                     sum=sum-z[i],s--;
    71                 else
    72                     sum+=z[i];
    73             }
    74             sum+=sum2*(-1);
    75         }
    76         cout<<sum<<endl;
    77     }
    78     return 0;
    79 }
    View Code

    补充:

    • 前缀表达式求值

    例如前缀表达式“- × + 3 4 5 6”计算的步骤如下:

    (1) 从右至左扫描,将6、5、4、3压入堆栈;
    (2) 遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;
    (3) 接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;
    (4) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

    • 后缀表达式:又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。

    后缀表达式计算:

    例如:后缀表达式为“2 3 + 4 × 5 -”计算过程如下:
      (1)从左至右扫描,将 2 和 3 压入堆栈;
      (2)遇到 + 运算符,因此弹出 3 和 2( 3 为栈顶元素,2 为次顶元素,注意与前缀表达式做比较),计算出 3+2 的值,得 5,再将 5 入栈;
      (3)将 4 入栈;
      (4)接下来是 × 运算符,因此弹出 4 和 5,计算出 4 × 5 = 20,将 20 入栈;
      (5)将 5 入栈;
      (6)最后是-运算符,计算出 20-5 的值,即 15,由此得出最终结果。

    • 中缀表达式的话就是一般我们看到的那种正常表达式啦

    [蓝桥杯2019初赛]不同子串

    题意:判断原串中有多少不同字串

    思路:暴力+set即可

    AC代码:

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<map>
     5 #include<set>
     6 using namespace std;
     7 const int N=100020;
     8 typedef long long ll;
     9 
    10 set<string>s;
    11 
    12 int main()
    13 {
    14     string ss,a;
    15     a="0100110001010001";
    16     for(int i=0;i<a.length();i++)
    17     {
    18         ss.clear();
    19         ss+=a[i];
    20         s.insert(ss);
    21         for(int j=i+1;j<a.length();j++)
    22         {
    23              ss+=a[j];
    24              s.insert(ss);
    25         }
    26     }
    27     cout<<s.size()<<endl;
    28     return 0;
    29 }
    View Code

    [蓝桥杯2019初赛]修改数组

    给定一个长度为N 的数组A = [A1, A2,...,AN],数组中有可能有重复出现的整数。
    现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改A2,A3,..., AN。
    当修改Ai 时,小明会检查Ai 是否在A1~ Ai-1 中出现过。
    如果出现过,则小明会给Ai 加上1 ;
    如果新的Ai 仍在之前出现过,小明会持续给Ai 加1 ,直到Ai 没有在A1~Ai-1中出现过。
    当AN 也经过上述修改之后,显然A数组中就没有重复的整数了。
    现在给定初始的A 数组,请你计算出最终的A 数组。

    输入

    第一行包含一个整数N(1<=N<=100000)
    第二行包含N个整数A1,A2,...,AN(1<=Ai<=1000000)

    输出

    输出N个整数,依次是最终的A1,A2,...,AN

    样例输入 

    5
    2 1 1 3 4

    样例输出 

    2 1 3 4 5

    思路:一开始的想法,我用book把之前没有出现过的标记,出现过的while进行暴力,但会造成超时,拿不到全部的分数,貌似80%,感觉也没有什么新奇的思路,于是查了一下,有新奇的思路->并查集

    参考博客:https://blog.csdn.net/weixin_42765557/article/details/89480557

    如何引入和判断并查集关键:

        for(int i=0; i<n; i++)
        {
            cin>>a[i];
            int x=getf(a[i]);
            a[i]=x;
            f[x]=getf(x+1);
        }

    AC代码:

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=100020;
     6 typedef long long ll;
     7 
     8 int a[N],f[N];
     9 
    10 int getf(int x)
    11 {
    12     if(x==f[x])
    13         return x;
    14     return f[x]=getf(f[x]);
    15 }
    16 
    17 int main()
    18 {
    19     for(int i=1; i<=N; i++)
    20         f[i]=i;
    21     int n;
    22     cin>>n;
    23     for(int i=0; i<n; i++)
    24     {
    25         cin>>a[i];
    26         int x=getf(a[i]);
    27         a[i]=x;
    28         f[x]=getf(x+1);
    29     }
    30     for(int i=0; i<n-1; i++)
    31         cout<<a[i]<<" ";
    32     cout<<a[n-1]<<endl;
    33     return 0;
    34 }
    View Code

    待解决:

    • 蓝桥杯后缀表达式,原因写在上面题目之后了
  • 相关阅读:
    回首2016,展望2017
    认识多线程
    对CloseHandle用法的理解
    CDC、HDC、pDC之间的关系
    兼容位图和兼容DC的理解
    窗口中显示bmp图片的过程
    创建一个bmp格式的简单方法
    说明为什么Button控件不能使用CustomDraw技术
    MFC自绘Button按钮分析和实现
    VC之美化界面篇
  • 原文地址:https://www.cnblogs.com/OFSHK/p/12309309.html
Copyright © 2020-2023  润新知