title: ACM-学习记录-数据结构-1
tags:

  • ACM
    abbrlink: ec23b92c
    date: 2020-11-24 14:39:32

AOJ-ALDS1_1_D Maximum Profit

本题主要考虑要将复杂度降到O(n),否则过不了最后五组数据

  1. #include<iostream>
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int main(){
  5. int n,maxv=-1e10;
  6. int stock[200000 + 5];
  7. cin>>n;
  8. for(int i=0;i<n;i++)
  9. {
  10. cin>>stock[i];
  11. }
  12. int minv=stock[0];
  13. for(int j=1;j<n;j++)
  14. {
  15. maxv=max(maxv, stock[j]-minv);
  16. minv=min(minv, stock[j]);
  17. }
  18. cout<<maxv<<endl;
  19. return 0;
  20. }

STL标准库

栈stack

函数名 功能 复杂度
size() 返回栈的元素数 O(1)
top() 返回栈顶元素 O(1)
pop() 从栈中取出并删除元素 O(1)
push() 添加元素x O(1)
empty() 在栈为空时返回true O(1)

ALDS1_3_A Stack

  1. #include<iostream>
  2. #include<cstdlib>
  3. #include<stack>
  4. using namespace std;
  5. int main()
  6. {
  7. stack<int> s;
  8. int a,b,x;
  9. string str;
  10. while(cin>>str)
  11. {
  12. if(str[0]=='+')
  13. {
  14. a=s.top(); s.pop();
  15. b=s.top(); s.pop();
  16. s.push(a+b);
  17. }
  18. else if(str[0]=='-')
  19. {
  20. b=s.top(); s.pop();
  21. a=s.top(); s.pop();
  22. s.push(a-b);
  23. }
  24. else if(str[0]=='*')
  25. {
  26. a=s.top(); s.pop();
  27. b=s.top(); s.pop();
  28. s.push(a*b);
  29. }
  30. else
  31. {
  32. s.push(atoi(str.c_str()));
  33. }
  34. }
  35. cout<<s.top()<<endl;
  36. return 0;
  37. }

队列queue

函数名 功能 复杂度
size() 返回队列元素数 O(1)
front() 返回队头元素
pop() 从队列中取出并删除元素
push() 向队列中添加元素
empty() 在队列为空时返回true
  1. #include<iostream>
  2. #include<string>
  3. #include<queue>
  4. #include<algorithm>
  5. using namespace std;
  6. int main()
  7. {
  8. int n,q,t;
  9. string name;
  10. queue<pair<string, int> > Q;
  11. cin>>n>>q;
  12. for(int i=0;i<n;i++)
  13. {
  14. cin>>name>>t;
  15. Q.push(make_pair(name, t));
  16. }
  17. pair<string ,int> u;
  18. int elap=0,a;
  19. while(!Q.empty())
  20. {
  21. u=Q.front(); Q.pop();
  22. a=min(u.second, q);
  23. u.second-=a;
  24. elap+=a;
  25. if(u.second>0)
  26. {
  27. Q.push(u);
  28. }
  29. else
  30. {
  31. cout<<u.first<<" "<<elap<<endl;
  32. }
  33. }
  34. return 0;
  35. }

vector

函数名 功能
size() 返回向量的元素数
push_back() 在向量末尾添加元素x
pop_back() 删除向量的最后一个元素
begin() 返回指向向量开头的迭代器
end() 返回指向向量末尾的迭代器
insert(p,x) 在向量的位置p处插入元素x
erase(p) 删除向量中位置p的元素
clear() 删除向量中的所有元素

双向链表List

函数名 功能
size() 返回表的元素数
begin() 返回指向表开头的迭代器
end() 返回指向表末尾的迭代器
push_front(x) 在表开头添加元素x
push_back(x) 在表末尾添加元素x
pop_front() 删除位于表开头的元素
pop_back() 删除位于表末尾的元素
insert(p, x) 在表的位置p处插入元素x
erase(p) 删除表中位置p的元素
clear() 删除表中所有元素

ALDS1_3_C: Doubly Linked List

  1. #include<iostream>
  2. #include<cstdlib>
  3. #include<list>
  4. #include<algorithm>
  5. #include<string>
  6. using namespace std;
  7. int main()
  8. {
  9. int q,x;
  10. string command;
  11. list<int> v;
  12. cin>>q;
  13. for(int i=0;i<q;i++)
  14. {
  15. cin>>command;
  16. if(command[0]=='i')
  17. {
  18. cin>>x;
  19. v.push_front(x);
  20. }
  21. else if(command[6]=='L')
  22. {
  23. v.pop_back();
  24. }
  25. else if(command[6]=='F')
  26. {
  27. v.pop_front();
  28. }
  29. else if(command[0]=='d')
  30. {
  31. cin>>x;
  32. for(list<int>::iterator it=v.begin();it!=v.end();it++)
  33. {
  34. if(*it == x)
  35. {
  36. v.erase(it);
  37. break;
  38. }
  39. }
  40. }
  41. }
  42. int i=0;
  43. for(list<int>::iterator it=v.begin(); it!=v.end();it++)
  44. {
  45. if(i++) cout<<" ";
  46. cout<<*it;
  47. }
  48. cout<<endl;
  49. return 0;
  50. }

ALDS1_3_D: Areas on the Cross-Section Diagram

  • 如果是“\”,则将表示该字符位置的整数i压入栈S1
  • 如果是“/”,则送S1顶部取出与之对应的””的位置i,算出二者的距离并累加到总面积内
  • ”的作用只是将一对/距离增加1,然而在代码中已经通过数学方法计算了,因此可以忽略掉”_“符号
  • 新形成的面积=当前S2中的两个面积之和+新形成的i-j部分的面积,从S1中取出被引用的多个面积,再将新算出的面积压入S2。
  1. #include<iostream>
  2. #include<cstdlib>
  3. #include<stack>
  4. #include<algorithm>
  5. #include<vector>
  6. using namespace std;
  7. int main()
  8. {
  9. stack<int> S1;
  10. stack<pair<int ,int> > S2;
  11. char c;
  12. int sum=0;
  13. for(int i=0;cin>>c;i++)
  14. {
  15. if(c=='\\') S1.push(i);
  16. else if(c=='/' && S1.size()>0)
  17. {
  18. int j=S1.top(); S1.pop();
  19. sum+=i-j;
  20. int a=i-j;
  21. while(S2.size()>0 && S2.top().first>j)
  22. {
  23. a+=S2.top().second; S2.pop();
  24. }
  25. S2.push(make_pair(j, a));
  26. }
  27. }
  28. vector<int> ans;
  29. while(S2.size()>0)
  30. {
  31. ans.push_back(S2.top().second);
  32. S2.pop();
  33. }
  34. reverse(ans.begin(),ans.end());
  35. cout<<sum<<endl;
  36. cout<<ans.size();
  37. for(int i=0;i<ans.size();i++)
  38. {
  39. cout<<" "<<ans[i];
  40. }
  41. cout<<endl;
  42. }

迭代器

基本运算符

符号 作用
++ 让迭代器指向至下一元素
==,!= 判断两个迭代器是否指向同一位置并返回结果
= 将右侧的值代入左侧迭代器所引用的元素的位置
* 返回该位置的元素

lower_bound

返回一个指向第一个不小于指定值value的元素

排序sort

stable_sort较稳定

sort的应用

1、可以传入两个参数;

sort(a,a+N) ,其中a是数组,a+N表示对a[0]至a[N-1]的N个数进行排序(默认从小到大排序);

2、传入三个参数;

sort(a,a+N,cmp),第三个参数是一个函数 ;

如果让函数从大到小排序,可以用如下算法实现;

bool cmp(int a,int b){return a>b};

sort(A,A+N,cmp);

stable_sort的用法与sort一致,区别是stable_sort函数遇到两个数相等时,不对其交换顺序;这个应用在数组里面不受影响,当函数参数传入的是结构体时,会发现两者之间的明显区别;

ALDS1_6_D: Minimum Cost Sort

  1. #include<iostream>
  2. #include<cstdlib>
  3. #include<algorithm>
  4. using namespace std;
  5. const int maxn=1000;
  6. const int vmax=10000;
  7. int n,a[maxn],s;
  8. int b[maxn],t[vmax+1];
  9. int solve()
  10. {
  11. int ans=0;
  12. bool v[maxn];
  13. for(int i=0;i<n;i++)
  14. {
  15. b[i]=a[i];
  16. v[i]=false;
  17. }
  18. sort(b,b+n);
  19. for(int i=0;i<n;i++)
  20. {
  21. t[b[i]] = i;
  22. }
  23. for(int i=0;i<n;i++)
  24. {
  25. if(v[i]) continue;
  26. int cur=i,m=vmax,an=0,S=0;
  27. while(1)
  28. {
  29. v[cur]=true;
  30. an++;
  31. int V=a[cur];
  32. m=min(m,V);
  33. S+=V;
  34. cur=t[V];
  35. if(v[cur]) break;
  36. }
  37. ans+=min(S+(an - 2) *m, m+S+(an+1)*s);//2SOLUTIONS
  38. }
  39. return ans;
  40. }
  41. int main()
  42. {
  43. cin>>n;
  44. s=vmax;
  45. for(int i=0;i<n;i++)
  46. {
  47. cin>>a[i];
  48. s=min(s,a[i]);
  49. }
  50. int ans=solve();
  51. cout<<ans<<endl;
  52. return 0;
  53. }

动态规划DP

LCS

  1. #include<iostream>
  2. #include<string>
  3. #include<algorithm>
  4. #include<cstring>
  5. const int N=1000;
  6. int c[N+5][N+5];
  7. using namespace std;
  8. int lcs(string X, string Y)
  9. {
  10. int m=X.length();
  11. int n=Y.length();//也可.size()
  12. int maxl=0;
  13. X=' '+X;
  14. Y=' '+Y;
  15. for(int i=1;i<=m;i++) c[i][0]=0;
  16. for(int j=1;j<=n;j++) c[0][j]=0;
  17. for(int i=1;i<=m;i++)
  18. {
  19. for(int j=1;j<=n;j++)
  20. {
  21. if(X[i]==Y[j])
  22. {
  23. c[i][j]=c[i-1][j-1]+1;
  24. }
  25. else
  26. {
  27. c[i][j]=max(c[i-1][j], c[i][j-1]);
  28. }
  29. maxl=max(maxl, c[i][j]);
  30. }
  31. }
  32. return maxl;
  33. }
  34. int main()
  35. {
  36. string s1,s2;
  37. int n;
  38. cin>>n;
  39. for(int i=0;i<n;i++)
  40. {
  41. cin>>s1>>s2;
  42. cout<<lcs(s1,s2)<<endl;
  43. }
  44. return 0;
  45. }