找的有关stl的零碎
https://www.dotcpp.com/oj/train/1012/
1.
set知识点/reverse函数知识点/sort函数知识点
/*
每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),
第二行包含n个各不相同,且都处于区间[-500000,500000]的整数
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;//
int main(){
ll n,m;
cin>>n>>m;
set<ll,greater<ll>> M;//
ll par;
for(int i=1;i<=n;i++){
cin>>par;
M.insert(par);
}
set<ll,greater<ll>>::iterator iter=M.begin();
for( int i=1;i<=m;i++){
cout<<*iter<<" ";
iter++;
}
}
//因为是从大到小排序: 这些都是默认有小到大的所以得改
//或者是用sort函数 sort(a,a+n,greater<ll>())
//或者是用反转函数reverse():sort(a,a+n),reverse(a,a+n);
- https://www.dotcpp.com/oj/problem2060.html
c++除法是去尾/set虽然能自动由小到大排序 但是也会自动删除重复元素
accumulate函数
#include<bits/stdc++.h>
using namespace std;
int a[105];
int main(){
int n;
while(cin>>n,n){
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]=a[i]/2+1;
}
sort(a+1,a+n+1);
cout<<accumulate(a+1,a+1+n/2+1,0)<<endl;
}
return 0;
}
- https://www.luogu.com.cn/problem/P1427
vector和reverse函数结合
#include<bits/stdc++.h>
using namespace std;
//P1427 小鱼的数字游戏
int main(){
int a;
vector<int>num;
while(cin>>a&&a){//!
num.push_back(a);//!
}
reverse(num.begin(),num.end());//!
for(int i=0;i<num.size();i++){//!
cout<<num[i]<<" ";//!
}
return 0;
}
- 符号匹配https://www.luogu.com.cn/problem/P1739
匹配括号:保证最后左右括号相等以及实时左括号数量多于右括号数量
大佬:https://blog.csdn.net/qq_44826711/article/details/113814132 他判断是左右括号后直接左括号++右括号--(符合数学常理,右括号消耗最近的左括号)最后直接判断sum是否0
重点没说妈蛋,我的在string上花了很久string=“”而不是‘’;判断相等那里也是加了下标【0】,push_back的时候得是字符串(因为容器是string的)
count函数的时候也是对容器类型string操作的,说白了就是string【】操作的对象是‘’单个字符:s1[0]'x':true
#include<bits/stdc++.h>
using namespace std;
//统计vector容器中指定对象元素出现的次数:count(): num1=count(s.begin(),s.end(),"(");
int main(){
string par;
cin>>par;
vector<string>s;
string k1="(";string k2=")";
int num1=0,num2=0;
int i=0;
while(i<par.length()){
if(par[i]==k1[0]){
s.push_back("(");
}
if(par[i]==k2[0]){
s.push_back(")");
}
i++;
//一定要实时保证(的个数比)个数多或者相等
num1=count(s.begin(),s.end(),"(");
num2=count(s.begin(),s.end(),")");
if(num1<num2){ //不等直接说明不匹配
cout<<"NO"<<endl;
return 0;//!!!!这样可以直接结束程序
}
}
if(num1==num2){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
return 0;
}
5.约瑟夫杀人问题
#include<bits/stdc++.h>
using namespace std;
//约瑟夫问题 就是用队列啦
/*
首先我们需要模拟一个队列,将所有的元素压进队列
在进行循环(直到队列为空为止) 首先你要知道:
队列只可以在head删除,那么这就要求我们只要这个人经过判断并且不会被剔除,那么就必须把他排在队尾;
若这个人正好被剔除,那先输出他,再踢除。
*/
queue<int> a;
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
a.push(i);
}
int position=1;
while(!a.empty()){
if(position==m){//它要出队列
cout<<a.front()<<" ";
a.pop();//直接pop就行
position=1;
}else{
position++;
a.push(a.front());//把他放到队尾再pop
a.pop();
}
}
return 0;
}
/*经典做法:约瑟夫的杀人题目https://www.luogu.com.cn/problem/P1996
int main()
{
cin>>m>>n>>k;//输入 PS:我把n,m打反了,大家凑合着看-_-||
for(int i=0;i<m;i++)
a[i]=i+1;//建立一个模拟链表
int p=0;//起始点
for (;m>0;--m)//开始杀人(´⊙ω⊙`)
{
p=(p-1+n%m+m)%m;//找出倒霉的那个人的位置,也是核心公式
cout<<a[p]<<(m==1?'\n':' ');//手起刀落
copy(a+p+1,a+m,a+p);//(O_O)?
}
return 0;
}
1.p=(p+n%m-1+m)%m很多人问这是什么,我给大家解释一下,其实所有约瑟夫杀人问题都可以套这个公式。
p相当于指针,指向下一个要被杀的人;
再加上p是由于这一回要从p的位置开始数,所以+p;
减去1是因为p本身也数,我们多数了一个,所以减去1;
n%m是由于n可能会比m打,为了减小运算量,对他先取余;
只要有减法就可能会出现负数,防止越界要再多数一圈,也就是加m;
最后再对m取余,得出p——下个被杀出圈的人。
2.copy(a+p+1,a+m,a+p);大家更好奇的也许是这个小东西,是时候让他闪亮登场啦!【鲜花,掌声】
我们先声明一个数组a,copy需要三个参数。例如:copy(a+1,a+i+1,a+i);表示把a+1到a+i+1这区间的数拷贝到首地址是a+i的数组元素中,其原来的数值将被覆盖。
那么copy(a+p+1,a+m,a+p);大家就不难理解了,在这里正好起到了一个把刚被杀死的人从圈里踢出的作用。正好循环里写的是m--,同时圈内的人数也减少了一个,不影响运算。
STL算法系列6---copy函数:该算法主要用于容器之间元素的拷贝,即将迭代器区间[first,last)的元素复制到由复制目标result给定的区间[result,result+(last-first))中
*/
- 卡特兰数:https://www.bilibili.com/video/BV1vb411p7ZN?from=search&seid=16772495674509774107
看完了就懂得https://www.bilibili.com/video/BV1y541187XV?from=search&seid=16772495674509774107 为什么说是符号匹配的问题
以及来源:这个视频就不贴了 感觉后面怪惊悚的