zoukankan      html  css  js  c++  java
  • 洛谷线性数据结构刷题总结

    题目链接

    1.约瑟夫问题P1996

    2.最大子段和P1115

    3.表达式括号匹配P1739

    4.队列安排P1160

    5.后缀表达式P1449

    约瑟夫问题是一个很经典的围圈报数的问题,比较简单,直接模拟就可以了

     1 #include <iostream>
     2 #include <cstring>
     3 #include <string>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <stack>
     7 #include <list>
     8 #include <stdio.h>
     9 #include <cmath>
    10 #include <string.h>
    11 
    12 #define ll long long
    13 using namespace std;
    14 bool num[105];
    15 int main()
    16 {
    17     freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
    18     int n,m;
    19     cin>>n>>m;
    20     int i=1;
    21     int cnt=0;
    22     int ans=0;
    23     while(ans!=n)
    24     {
    25         if(!num[i])
    26         {
    27             cnt++;
    28             if(cnt==m)
    29             {
    30                 cout<<i<<" ";
    31                 num[i]=true;
    32                 cnt=0;
    33                 ans++;
    34             }
    35         }
    36         i++;
    37         if(i==n+1)
    38         i=1;
    39     }
    40     return 0;
    41 }

    最大子段和是一个入门的DP,状态转移方程可以很容易的写出来,我们假设sum[i]是以i为终点的最大子段和,那么要判断sum[i]就有两种情况

    1. 若sum[i-1]<=0,sum[i]=num[i]。若以i-1为终点的最大子段和都小于等于零,不如不取,直接以第i个数作为最大子段和是最大的情况。

    2. 若sum[i-1]>0, sum[i]=sum[i-1]+num[i]。若以i-1为终点的最大子段和大于零,自然要取前一段,保证最大。

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <stdio.h>
    #include <cmath>
    #include <string.h>
    
    #define ll long long
    using namespace std;
    int num[200005];
    int sum[200005];
    int main()
    {
        //freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
        int n;
        int max_num=-99999;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>num[i];
        for(int i=1;i<=n;i++)
        {
            if(sum[i-1]<=0)
            sum[i]=num[i];
            else
            sum[i]=sum[i-1]+num[i];
            max_num=max(sum[i],max_num);
        }
        cout<<max_num<<endl;
        return 0;
    }

     表达式括号匹配,只要满足一个思路即为匹配。

     定义一个变量,每出现一个左括号++,每出现一个右括号且当该变量大于零的时候--,当判断完所有字符以后,若该变量等于0,则匹配。这样可以避免)(a+b)(的情况。

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <stdio.h>
    #include <cmath>
    #include <string.h>
    
    #define ll long long
    using namespace std;
    
    int main()
    {
        //freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
        string str;
        cin>>str;
        int num=0;
        bool flag=true;
        for(int i=0;i<str.size();i++)
        {
            if(str[i]=='(')
            num++;
            else if(str[i]==')')
            {
                if(num>0)
                num--;
                else
                {
                    flag=false;
                    break;
                }  
            }
        }
        if(num==0&&flag)
        cout<<"YES"<<endl;
        else
        cout<<"NO"<<endl;
        return 0;
    }

     队列安排应该是这里面最难的一题,因为我个人觉得C++的STL里面的list是最难使用的,而这里恰好需要用到list(当然手写链表的大佬请直接忽略)

    注意:在C++11的标准下会编译失败,只有在14的标准下才能AC。

    //在C++11标准下不能通过,只能在C++14的标准下才能通过
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <stdio.h>
    #include <cmath>
    #include <string.h>
    #include <list>
    
    #define ll long long
    using namespace std;
    list <int> v;//创建空链表
    using Iter=list <int> ::iterator;
    list<int> ::iterator it;//创建一个迭代器
    Iter pos[100005];//创建一个迭代器的数组,pos[i]是第i号同学的迭代器
    bool f[100005];
    int main()
    {
        //freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
        int n,k,p,m;
        cin>>n;
        v.push_back(1);
        pos[1]=v.begin();
        for(int i=2;i<=n;i++)
        {
            cin>>k>>p;
            if(p==0)
            pos[i]=v.insert(pos[k],i);
            else
            {
                auto nextIter=next(pos[k]);
                pos[i]=v.insert(nextIter,i);
            }
        }
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>k;
            f[k]=true;
        }
        for(it=v.begin();it!=v.end();it++)
        {
            if(!f[*it])
            cout<<*it<<" ";
        }
        return 0;
    }

    最后一题后缀表达式也比较简单,直接模拟就可以啦

     1 #include <iostream>
     2 #include <cstring>
     3 #include <string>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <stack>
     7 #include <stdio.h>
     8 #include <cmath>
     9 #include <string.h>
    10 
    11 #define ll long long
    12 using namespace std;
    13 stack<int> sta;
    14 queue<int> que;
    15 int main()
    16 {
    17     //freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
    18     string str;
    19     cin>>str;
    20     for(int i=0;i<str.size();i++)
    21     {
    22         if(str[i]-'0'>=0&&str[i]-'0'<=9)
    23         que.push(str[i]-'0');
    24         else if(str[i]=='.'&&!que.empty())
    25         {
    26             int a=0;
    27             while(!que.empty())
    28             {
    29                 a=a*10+que.front();
    30                 que.pop();
    31             }
    32             sta.push(a);
    33         }
    34         else if(str[i]=='+')
    35         {
    36             int a,b;
    37             a=sta.top();
    38             sta.pop();
    39             b=sta.top();
    40             sta.pop();
    41             sta.push(a+b);
    42         }
    43         else if(str[i]=='-')
    44         {
    45             int a,b;
    46             a=sta.top();
    47             sta.pop();
    48             b=sta.top();
    49             sta.pop();
    50             sta.push(b-a);
    51         }
    52         else if(str[i]=='*')
    53         {
    54             int a,b;
    55             a=sta.top();
    56             sta.pop();
    57             b=sta.top();
    58             sta.pop();
    59             sta.push(a*b);
    60         }
    61         else if(str[i]=='/')
    62         {
    63             int a,b;
    64             a=sta.top();
    65             sta.pop();
    66             b=sta.top();
    67             sta.pop();
    68             sta.push(b/a);
    69         }
    70     }
    71     cout<<sta.top()<<endl;
    72     return 0;
    73 }
  • 相关阅读:
    大胆决定+细致用功, 才可能改变命运
    采用用同步编程的方式实现跨进程异步获取数据
    关于DataGridViewComboBoxCell修改后提交数据源
    学习:如何具有坚韧的性格
    汉语-成语:坚韧不拔
    汉语-词语:坚韧
    阿里云-OSS-Help-SKD参考-.NET:前言
    阿里云-OSS-OSS管理控制台:Bucket列表
    阿里云-OSS-OSS管理控制台:概览
    汉语-词语:推理
  • 原文地址:https://www.cnblogs.com/zlhdbk/p/11269797.html
Copyright © 2011-2022 走看看