一、容器
1、vector
vector 是STL的动态数组,索引可以在常数时间内完成,插入或删除中间某一项需要线性时间,时间复杂度是O(n)
vector<int> b(a); //用a定义b vector<int> a(100); //a有100个值为0的元素 vector<int> a(100, 6) //a有100个值为6的元素 vector<string> a(10, "hello"); vector<string> b(a.begin(), a.end()); // b是a的复制 a.insert(a.begin() + i, k); // 在第i个元素前插入k a.erase(a.begin() + i, a.bejin() + j); //删除区间[i, j - 1]的元素 a.erase(a.begin() + 2); // 删除第三个元素 reverse(a.begin(), a.end()); //翻转数组
hdu 4841
//#include <bits/stdc++.h> #include <vector> #include <iostream> using namespace std; int main(){ vector<int> table; int n, m; while(cin >> n >> m){ table.clear(); for(int i = 0; i < 2 * n; i++) table.push_back(i); int pos = 0; for(int i = 0; i < n; i++){ pos = (pos + m - 1) % table.size(); table.erase(table.begin() + pos); } int j = 0; for(int i = 0; i < 2 * n; i++){ if(!(i % 50) && i) cout << endl; if(j < table.size() && i == table[j]){ j++; cout << "G"; } else cout << "B"; } cout << endl << endl; } return 0; }
2、stack、queue
栈需要空间存储,如果深度太大,或者存储进栈的数组太大,那么总数会超过系统为栈分配的空间,这样就会爆栈,即栈溢出
可以手工写栈解决这个问题
// stack s.push(item); s.top(); s.pop(); s.size(); s.empty(); // queue q.push(item); q.front(); //返回队首元素,但不会删除 q.pop(); // 删除队首元素 q.back(); // 返回队尾元素
hdu 1062
//#include <bits/stdc++.h> #include <iostream> #include <stack> using namespace std; int main(){ int n; char ch; scanf("%d", &n); getchar(); while(n--){ stack<char> s; while(true){ ch = getchar(); if(ch == ' ' || ch == '\n' || ch == EOF){ while(!s.empty()){ printf("%c", s.top()); s.pop(); } if(ch == '\n' || ch == EOF) break; printf(" "); } else s.push(ch); } printf("\n"); } return 0; }
hdu 1702c //#include <bits/stdc++.h> #include <iostream> #include <stack> #include <string> #include <queue> #include <stack> using namespace std; int main(){ int t, n, temp; cin >> t; while(t--){ string str, str1; queue<int> Q; stack<int> S; cin >> n >> str; for(int i = 0; i < n; i++) { if (str == "FIFO") { cin >> str1; if (str1 == "IN") { cin >> temp; Q.push(temp); } if (str1 == "OUT") { if (Q.empty()) cout << "None" << endl; else { cout << Q.front() << endl; Q.pop(); } } } else { cin >> str1; if (str1 == "IN") { cin >> temp; S.push(temp); } if (str1 == "OUT") { if (S.empty()) cout << "None" << endl; else { cout << S.top() << endl; S.pop(); } } } } } return 0; }
3、list
list是数据结构的双向链表,它的内存空间可以是不连续的,通过指针进行数据的访问,它可以高效的在任意地方删除和插入,插入和删除操做是常数时间的。
list 和 vector 的优缺点正好相反,它们的应用场景不同。
(1)vector:插入和删除次数较少,随机访问元素频繁。
(2)list:插入和删除频繁,随机访问较少。
hdu 1276
//#include <bits/stdc++.h> #include <iostream> #include <stack> #include <string> #include <queue> #include <stack> #include <list> using namespace std; int main(){ int t, n; cin >> t; while(t--){ cin >> n; int k = 2; list<int> mylist; list<int>:: iterator it; for(int i = 1; i <= n; i++) mylist.push_back(i); while(mylist.size() > 3){ int num = 1; for(it = mylist.begin(); it != mylist.end();){ if(num++ % k == 0){ it = mylist.erase(it); } else it++; } k == 2? k = 3: k = 2; } for(it = mylist.begin(); it != mylist.end(); it++){ if(it != mylist.begin()){ cout << " "; } cout << *it; } cout << endl; } return 0; }
4、set
set 就是集合。STL的set用二叉搜索树实现,集合中的每一个元素只出现一次,并且是排好序的。访问元素的时间复杂度是O(logn) 非常高效。
a.insert(item); //插入 a.erase(item); //删除 a.find(k); //返回一个迭代器,指向k a.lower_bound(); // 返回一个迭代器,指向键值不小于k的第一跟元素 a.upper_bound(); // 返回一个迭代器,指向键值大于k的第一个元素
hdu 2094
//#include <bits/stdc++.h> #include <iostream> #include <stack> #include <string> #include <queue> #include <stack> #include <set> #include <list> using namespace std; int main(){ set<string> A, B; string s1, s2; int n; while (cin >> n && n){ for(int i = 0; i < n; i++){ cin >> s1 >> s2; A.insert(s1); A.insert(s2); B.insert(s2); } if(A.size() - B.size() == 1){ cout << "Yes" << endl; } else cout << "No" << endl; A.clear(); B.clear(); } return 0; }
5、map
利用STL中的map实现查找,复杂度是O(logn)
hdu 2648
//#include <bits/stdc++.h> #include <iostream> #include <stack> #include <string> #include <queue> #include <stack> #include <set> #include <list> #include <map> using namespace std; int main() { int n, m, p; map<string, int> shop; while (cin >> n){ string s; for(int i = 1; i <= n; i++) cin >> s; cin >> m; while(m--){ for(int i = 1; i <= n; i++){ cin >> p >> s; shop[s] += p; } int rank = 1; map<string, int>::iterator it; for(auto it: shop){ if(it . second > shop["memory"]) rank ++; } cout << rank << endl; } shop.clear(); } return 0; }
二、常用函数
1、sort()
复杂度O(nlogn)
它的排序范围是[first, last),包括first,不包括last。
//#include <bits/stdc++.h> #include <iostream> #include <stack> #include <string> #include <queue> #include <stack> #include <set> #include <list> #include <map> #include <algorithm> using namespace std; bool my_less(int i, int j) {return (i < j);} // 自定义升序 bool my_greater(int i, int j){return (i > j);} // 自定义降序 int main(){ vector<int> a = {3, 7, 2, 5, 6, 8, 5, 4}; sort(a.begin(), a.begin() + 4); // 对前四个排序 sort(a.begin(), a.end()); // 默认升序排列 sort(a.begin(), a.end(), less<int>()); sort(a.begin(), a.end(), my_less); sort(a.begin(), a.end(), greater<int>()); sort(a.begin(), a.end(), my_greater); for(int i = 0; i < a.size(); i++){ cout << a[i] << " "; } return 0; }
sort()还可以对结构体进行排序
struct Student{ char name[256]; int score; } bool cmp(struct Student* a, struct Student* b){ return a -> score > b -> score; } vector<struct struct*> list; sort(list.begin(), list.end(), cmp);
2、next_permulation()
STL提供求下一个排列组合的函数next_permulation()。例如3个字符a、b、c组成的序列,next_permulation()能按字典序返回六个组合,即abc,acb,bac,bca,cab,cba。
bool next_permulation(first,last);
返回值:如果没有下一个排列组合,返回false,否则返回true,每次执行next_permulation()会把新的排列放到原来的空间里。
hdu 1027
//#include <bits/stdc++.h> #include <iostream> #include <stack> #include <string> #include <queue> #include <stack> #include <set> #include <list> #include <map> #include <algorithm> using namespace std; int a[1001]; int main(){ int n, m; while(cin >> n >> m){ for(int i = 1; i <= n; i++) a[i] = i; int b = 1; do{ if(b == m) break; b++; }while(next_permutation(a + 1, a + 1 + n)); for(int i = 1; i < n; i++){ cout << a[i] << " "; } cout << a[n] << endl; } return 0; }