写的有些久,拖到7-14号凌晨才写完,因为我自己也在慢慢理解中,还是要多做题,做的题越多,理解越深刻。
1. 栈:
stack是一种先进入的元素后弹出的数据结构。
有一种常见的栈的应用就是检查括号匹配与否。
对应题目及题解链接:https://blog.csdn.net/ericgipsy/article/details/79980874
2.队列与优先队列:
<队列>
queue与stack相反,是一种先进入的元素先弹出的数据结构。
先来一个队列的入门题:
题目:
本人AC代码:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxx = 1e3 + 7;
int n, m;
int a[maxx], b[maxx];
int ans;
queue qua;
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= m; i++) {
cin >> b[i];
qua.push(b[i]);
}
int ans = 0;
for(int i = 1; i <= n; i++) {
if(qua.front() >= a[i] && !qua.empty()) {
ans++;
qua.pop();
}
}
cout << ans << endl;
}
再就是,其中有一种应用就是约瑟夫环,可以理解为一个循环队列:
对应题目链接:https://vjudge.net/problem/OpenJ_Bailian-3254
本人AC代码:
#include
#include
#include
#include
#include
#include
#include
<优先队列>
优先队列是一种能形成自动排序的队列,分为升序(队头大)和降序(队头小),默认从大到小:
priority_queue
priority_queue
针对 pair 的优先队列,priority_queue
对应题目:Codeforces - 994B、Atcoder Beginner 062 - D
Codeforces - 994B 题解链接:https://blog.csdn.net/ericgipsy/article/details/80729562
Atcoder Beginner 062 - D 题解:
题意:
给定一个长度为3 * n的序列,在其中删除n个元素,问由剩下的2 * n个元素构成的新序列,前一半n个元素的和与后一半n个元素的和差值最大是多少。
思路:
序列分成三段长度为n的子序列,依题可知,肯定是用中间那段长度为n的子序列去替换两边的序列的某些元素,要想差值最大,那就需要将中间那段长度为n的序列内较大的元素尽可能替换左边序列的较小者,同理用中间序列的较小者替换右边序列的较大者。所以声明两个优先队列,一个升序一个降序,将左序列的元素压进升序的优先队列内,右序列压进降序的优先队列内,然后先将中间序列的元素向右推进,维护一个队头,处理出每个位置所能让左序列形成的最大的和,同理从右向左推进处理出每个位置所能让右序列形成的最大的和,然后对于 i 从 n ~ 2 * n,取suml[i] 与sumr[i + 1]所能形成的最大差值即为所求,之所以不是对应位置的两个数组做差,是因为中间序列的每个元素不能重复使用,左右枚举出来的区间必须是无缝对接的。
本人AC代码:
#include
#include
#include
#include
#include
#include
#include
3.树状数组:
树状数组主要有区间查询和单点更新两个操作,树状数组是一种低级的线段树。
树状数组初始化、区间求和、单点更新 模板:
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxx = 107;
int n;
int a[maxx];
int tree[maxx];
int lowbit(int x) {
return x & (-x);
}
int get_sum(int x) {
int sum = 0;
while(x > 0) {
sum += tree[x];
x -= lowbit(x);
}
return sum;
}
void update(int x, int t) {
while(x <= n) {
tree[x] += t;
x += lowbit(x);
}
}
int main() {
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) {
for(int j = i; j > i - lowbit(i); j--) tree[i] += a[j];
}
cout << get_sum(5) << endl;
cout << get_sum(6) - get_sum(2) << endl;
update(1, 1);
cout << get_sum(5) << endl;
cout << get_sum(6) - get_sum(2) << endl;
}