ACM总结(STL)

本文概述了STL(标准模板库)在ACM编程竞赛中的关键数据结构和算法,如Vector、Stack、优先队列、Map,以及去重、全排列、Upper_bound和lower_bound等实用技巧。掌握这些可以提高竞赛效率,解答第一、二题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ACM总结(STL)

今周总结一下STL的有关内容。因为STL在cf上或是在平常一些竞赛中经常可以被找到,一般以第一,二题的形式出现。而且竞赛中很多常用的数据结构、算法在STL中都有熟练地掌握它们可以极大的简化编程,它可以说是竞赛的信心来源因为,掌握它们一般可以快速的ac第一二(水题)道题。

  1. Vector(动态数组)

头文件:#include <vector>
定义:vector<type>s; //type数据类型,如int,char,string
s.push_back(k)//在数据尾插入值为k的元素
s.clear()//清空
s.insert(s.begin()+i,k)//在第i个元素前面插入k
s.erase(s.begin()+k)//删除第k+1个元素
s.erase(s.begin()+i,s.begin()+j)//删除区间[i,j-1]中所有元素
s.pop_back()//删除末尾元素
int size=s.size()//元素个数
运用示例
设计程序
将k个数中的奇数或偶数分别输出

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n;
int main()
{   vector<int>a;
    cin>>n;
    int k;
    a.clear();
    for(int q=0; q<n; q++)
    {   cin>>k;
        a.push_back(k);
    }
    for(int q=0; q<a.size();)
    {   if(a[q]%2==0)
        {
            q++;               // 注意:vector插入或删除中间某一项时这个元素后面的所有元素往后或往前移
        }
        else
        {a.erase(a.begin()+q);
        }
    }
    sort(a.begin(),a.end());
    for(int q=0; q<a.size(); q++)
    {
        cout<<a[q]<<" ";
    }

return 0;
}
  1. 栈(stack)

特点:先进后出
头文件:#include<stack>
定义:stack<type>s;//type数据类型,如int,char,string
s.push(k)//把k放到栈顶
s.top()//返回栈顶的元素
s.pop()//删除栈顶的元素
s.size()//返回栈中元素个数
s.empty()//检查元素是否为空,if为空,返回true,else返回false;
运用示例
翻转字符串(来自hdu 1062)
输入:“olleh !dlrow”
输出:“hello world!”

#include<iostream>
#include<algorithm>
#include<stack>
#include<cmath>
#include<stdio.h>
using namespace std;
int n;
char ch;
stack<char>a;
int main()
{cin>>n;
getchar();
while(n--)
{while(1)
{scanf("%c",&ch);//相当于ch=getchar()但是不能用cin>>因为cin不支持录入空格与回车键
//其实cin,scanf与getchar()都有缓冲区
//scanf只有在scanf("%c",&ch)的情况下才支持空格与回车键
if(ch==' '||ch=='\n'||ch==EOF)
{while(!a.empty())
{cout<<a.top();
a.pop();
}
if(ch==' ')
cout<<" ";
}
else
{a.push(ch);}
if(ch=='\n'||ch==EOF)
{break;}
}
cout<<endl;
}    
    return 0;
}

注:cin,scanf与getchar()都有缓冲区
这个是做题时看一些竞赛选手写的代码时,发现的当时看见感到很诧异,可以看看下面的代码

#include<iostream>
using namespace std;

int main()
{  int n,a;
cin>>n;
 for(int q=0;q<n;q++)
  {cin>>a;
if(a%2==0)
{cout<<a<<" ";}
}


    return 0;
}

是不是会营造一种边输入边输出的感觉!

  1. 优先队列(priority_queue)
    头文件:#include<queue>
    特点 : 顾名思义就是优先级最高的先出列,它是队列和排序的完美结合,不仅可以储存数据,还可以按照设定的规则进行排序。(用重载运算符对运算符重新定义),注意每次的push和pop操作,优先数列都会动态调整,把优先级最高的元素或按照设定的规则放在最前面。
struct node
{
    int x;
    int y;
};
priority_queue<node>q[5];//定义结构体类型的优先队列
bool operator <(const node &a,const node &b)//重载<运算符,指定优先规则
{
    if(a.x==b.x)//如果x相同,y由小到大
        return a.y>b.y;
    else
        return a.x<b.x;//x由大到小
}
  1. Map
    头文件:#include<map>
    定义:map<type1,type2>s://type1是对map下标类型的定义,type2是对map元素的定义。
    (例如:map<string,int>students;)可以同时储存学生的name与成绩(学号,排名等等)可以看做是一个拥有两个元素类型的结构体,但是map数组可以根据下标对数据精准查询,而结构体要搜索所有的元素,复杂度高效率低。
    Student[“yjj”]=99;
    5.去重函数(unique)
    特点:将相邻的元素进行去重。
    对于去重函数(unique),我一直有一个疑问就是,上课听课时好像讲的对于去重后的数,系统自动放到数组(队列)末,但是通过在cf上做题,我发现好像并没有将去重后的元素放到队列末,而是将排序后的元素放在了队列末。
    例如:
    输入:10
    4 5 6 7 7 3 5 5 8 3
    对该数组a[10]进行去重。
    排序完是:3 3 4 5 5 5 6 7 7 8
    而去重完是:3 4 5 6 7 8
    若是放到队列末全部输出是:3 4 5 6 7 8 (3 5 5 7 )
    而实际是:3 4 5 6 7 8 (6 7 7 8)和排序完的数组末一致
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b)
{   return a>b;
}
int main()
{
    int n,t;
    cin>>n;
    int a[100];
    for(int q=0; q<n; q++)
    {   cin>>a[q];
    }
    sort(a,a+n,cmp);  //去重前先进行排序。
    t=unique(a,a+n)-a;
    for(int q=0; q<t; q++)
    {
        cout<<a[q]<<" ";
    }
    return 0;
}

6.全排列(next_permutation())
特点:可以按照字典序依次生成元素排列的所有组合。
如:char[3]={a,b,c};
next_permutation()可以按字典序返回6个组合abc,acb,bac,bca,cab,cba。
本来该函数在之前无论是做题还是看书都不曾遇见过,但是在上次海理工大学第二届“联想杯”全国程序设计邀请赛上遇到过一次,但是突然想起了这个函数就试着用了,就ac了。
这是全排列用法:

#include <cstdio>
 #include <algorithm>
 #include <iostream>
 #include <cstring>
using namespace std;
int a[1000],n;
int main()
{  while(cin>>n)
   {memset(a,0,sizeof(a));
for(int q=0;q<n;q++)
{cin>>a[q];}
sort(a,a+n);
while(next_permutation(a,a+n))
{for(int q=0;q<n;q++)
{cout<<a[q];}
cout<<endl;
}
}
    return 0;
}

这是该题的代码:

#include<iostream>
#include<algorithm>
using namespace std;
long long n,a[9],b[9],c[100000];
int main()
{   cin>>n;
for(int q=0; q<n; q++)
    {   cin>>a[q];
    }
    for(int q=0; q<n; q++)
{   cin>>b[q];

    }
    sort(b,b+n);
    int l=0;
    while(next_permutation(b,b+n))
        {   for(int q=0; q<n; q++)
            {   if(__gcd(a[q],b[q])>1)
                    c[l]++;
            }
l++;
        }
    sort(c,c+l);
    cout<<c[l-1]<<endl;
    return 0;
}
//①__gcd(a,b)a,b的最大公约数。

7.Upper_bound和lower_bound
这个在上一篇博客里详细提到了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值