本篇介绍队列 queue。
1. 性质
队列是一种先进先出的数据结构。
简要文字模拟:
向队列插入一个 x
向队列插入一个 y
取出队列的元素取出的为 x,因为 x 最先放入队列
取出队列的元素取出的为 x,因为 x 最先放入队列,并且上次取出没有弹出
弹出队列顶部元素
取出队列的元素取出的为 y
弹出队列顶部元素
队列为空
2. 定义及头文件
#include<queue>//头文件queue</*填需要的类型*/>/*填队列名字*/;
3. 方法函数
操作 队列名为 dldldl
含义及复杂度
dl.front()
返回队首元素 OOO(111)
dl.pop()
弹出队首元素 OOO(111)
dl.back()
返回队尾元素 OOO(111)
dl.push(/*要加入队列的元素*/)
一个元素进队 OOO(111)
dl.size()
队列元素个数 OOO(111)
dl.empty()
队列是否为空 OOO(111)
注:判断队列是否为空,为空返回 1,否则返 ...
本篇介绍 vector 数组。
定义
// 一维vector</*填数组需要的类型*/>/*数组名字*/;// 以下以 int 类型示范//创建一个一维的 int 类型 vector 数组,数组名叫 szvector<int>sz;// 创建一个长度为 n 的数组vector<int>sz(n);// 创建一个长度为 n 的数组,并且数组内的所有值为 ivector<int>sz(n,i);// 二维vector<vector</*填数组需要的类型*/> >/*数组名字*/;vector<vector</*填数组需要的类型*/> >/*数组名字*/(/*第一维的大小*/,vector</*填数组需要的类型*/>(/*第二维的大小*/));// 以下以 int 类型示范// 创建一个类型为 int 的二维 vector 数组,名字叫szvector<vector<int> >sz;// 创建一个普通数组这么写 "int sz[5][10]&q ...
思路:
定义结构体,结构体包含三个成员 leftleftleft 表示左边的人,rightrightright 表示右边的人,czczcz 表示这两个人的差值,自定义排序:
bool operator <(const node &X)const{ return cz==X.cz?left>X.left:cz>X.cz;}
定义优先队列,类型为上面定义的结构体。
定义标记数组 bjbjbj 标记这个人是否已经被搭配了。
定义二维数组 ansansans 存答案。
定义 ans2ans2ans2 存答案的数量。
定义数组 lastlastlast 和 nexnexnex 模拟链表,记录上一个人和下一个人。
在输入时顺便把 lastlastlast 和 nexnexnex 初始化,初始化时 lastilast_ilasti 的值为 i−1i-1i−1,nexinex_inexi 的值为 i+1i+1i+1。
在输入完后,遍历字符串,直到现在遍历到的是字符串的最后一个字母,注意是遍历到而不是遍历完,当字符串的第 iii 个字符与第 i+1 ...
思路:
定义一个 unordered_set 用于标记出现过那些人,定义名字为 sesese。
定义一个 unordered_map 记录每个人所获得的分数,键为字符串类型,值为整形,定义名字为 personpersonperson。
定义结构体用于存每个人的分数,此结构体排序用。
观察题目所给出的操作的输入格式,发现操作的标志一定是在这一行的第二个字符串,而这一行字符串的数量一定大于三,所以我们可以先输入前三个字符串,然后判断第二个字符串是什么操作。
如果第二个字符串等于 likes 那么第三个字符串就是第二个人的名字。
如果第二个字符串为 posted 或 commented 时,那么第二个人名的位置就在第四个字符串,我们把他输入进来。
在输入找到第二个人的名字后,我们用 erase 把第二个人名后面多余的 's 删除,使这个字符串只有人名,然后判断第一个人名和第二个人名中有没有淘淘,因为只有和淘淘互动了,他跟淘淘的因子分数才会增加,然后再判断下这些人名有没有在 se 里面出现过,如果没有出现过就把他加入到里面,最后把这些操作里的最后一个字符串输入进来就行了。
我们用创建一个 ...
思路:
定义三个 unordered_map,两个 unordered_map 的键和值都是 int 类型,分别存被访问的次数定义名字为 mpmpmp 和是在什么时候存进来的定义名字为 jljljl,第三个 unordered_map 的键为 int 类型,而值为 vector 数组,用来存访问次数为键的内存页是几定义名字为 sesese。
定义 ccc 为需要访问的虚拟内存页的编号,再定义一个 minnminnminn 表示现在最少的访问次数。
如果要访问的内存页存在也就是 mp.count(c) 为一,那么让我们的答案加一,然后把 sesese 里的数组里的 ccc 删除,接着把 ccc 加入到 sesese 的键为这次操作后 ccc 被访问的次数的数组里,然后判断一下在这次操作后原本 sesese 的键为 minnminnminn 的数组大小是否为零,如果为零则代表 ccc 原本是这个数组里唯一的元素,而 ccc 的访问次数增加后,这个数组里就没有元素了,也就是最少的访问次数现在不是 minnminnminn 了而是 minnminnminn 加上一,我们让 minnminn ...
思路:
看题,需要在矩阵上找出一条起始点任意的路径(可以重复经过某个格子),使得字典序最大。
那么通过可以重复这四个字我们可以知道最后求出的字符串的长度一定是小于等于二的。
所以,我们可以在输入时查找最大的字母(为了保证字典序最大)用一个变量 ccc 存下来,输入完之后,历遍矩阵,当历遍到的字母为我们找到的最大的字母时,查找他上下左右四个方向的最大的字母,然后用 chchch 存下来。
最后在循环结束后在 ccc 与 chchch 不相同时输出 chchch 就可以了,相同的情况就不要输出了。
代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define itn int#define ull unsigned long long int n,m;char ch;char jz[1500][1500]; int dx[]={1,-1,0,0},dy[]={0,0,-1,1};int main(){ int mx=0,my=0; ch ...
思路:
直接按照题目进行模拟输出,题目有公式,可以直接看下面的公式,在输入后套公式输出就行了。
代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define itn int#define ull unsigned long longconst double j=sqrt(3)/2;int main(){ LL x,y;cin>>x>>y; printf("%.6lf %.6lf",0.5*x+0.5*y,j*x-j*y); return 0;}
思路:
使用 dfs 算法,创建一个数组存当前已经找到的数字。
深度优先搜索代码实现:传入的量为现在找的是第几个数,第一次传入的是一,表示现在找的是第一个数,当传入的数减一等于 mmm 时输出。
输出函数实现:循环定义的 iii 表示当前已经找到的数字的数组的下标,如果你下标是从零开始存的就从零历遍到 m−1m-1m−1,如果是从一开始存的就从 111 历遍到 mmm,注意不要忘了最后换行。
因为题目中要求字典序较小的排在前面,所以我们就不定义标记数组了,下一次搜索就直接从上一个数加一开始。
完整代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define itn int#define ull unsigned long longull n,m;ull sc[30];// 存现在找到的数字void print(){// 输出 for(int i=1;i<=m;i++)cout<<sc[i]<<" "; cout<&l ...
思路:
使用前缀和,考虑到输入的询问范围可能会有 lll 相同,所以先用一个结构体把输入的 lll 和 rrr 和输入的顺序存起来,然后进行排序哪个左端点更小,如果同时左端点相同,那么比较哪个右端点更小。
在 lll 相等时,我们可以直接按照上一个的答案往下搜这样重复的部分就不用重复计算历遍了。
为什么可以直接按照上一个的答案往下搜,因为我们在一开始排过序,只要这个结构体排完序后在前一个结构体后面,并且 lll 相同,那么后面的结构体的 rrr 一定大于等于前面的结构体的 rrr,所以可以直接按照上一个的答案往下搜。
当 lll 不相等时,就正常地直接历遍,然后存答案就可以了。
完整代码:
#include<bits/stdc++.h>using namespace std;#define ull unsigned long long#define LL long longull tamp;const int MAXN=10001;const int MAXQ=1000001;ull n,q;ull sum[MAXN];ull a[100010];struct nod ...
思路:
因为只有通过删除一个字符,或插入一个字符,或修改一个字符变成另一个字符串才是相似的,所以我们可以分成五种情况。
第一种情况,如果第一个字符串和第二个字符串是相同的,那么这两个字符串是相似的,代码如下。
if(a==b){// 特判如果 a 与 b 相同的情况 cout<<"similar\n";continue;}
第二种情况,如果第一个字符串的长度等于第二个字符串的长度且两个字符串不相同,如果它们是相似的,那么只能是修改一个字符出来的,两个字符串之间至少有第一个字符串的长度减一个字符是相同的,且位置相同,代码如下。
if(a.size()==b.size()){// a 的长度与 b 的长度相同 for(int i=0;i<a.size();i++){ if(a[i]==b[i])cnt++;// 都用 i 因为要在同一个位置 } if(cnt+1==a.size()||cnt==a.size()){// 至少有 a.size()-1 个字符相同且在同一个位置 co ...