洛谷线性数据结构刷题总结

题目链接

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 }
原文地址:https://www.cnblogs.com/zlhdbk/p/11269797.html