C++常用语法2(实用语法、STL库函数)

目录

一、实用语法

1.重载运算符

 2.随机数生成

①rand()

②mt19937()

二、STL库函数

1.algorithm

用法1:排序(sort)

用法2:去重(unique)

用法3:二分查找(lower_bound、upper_bound) 

用法4:全排列(next_permutation、prev_permutation)

用法 5:最大、最小(max、min)

用法6:交换(swap)

用法7:查找(find) 

2.stack(栈)

括号匹配

 3.queue(队列)

周末舞会

合并果子

4.vector(向量)

5.map(映射)

查字典

 6.set(集合)

集合的并

 7.memset(填充)

8.pair(对)

9.万能头文件

--------------------------------------------end--------------------------------------------


一、实用语法

1.重载运算符

众所周知,结构体是一个我们编程中非常常用的工具,但它有一个比较大的缺陷:不能直接进行操作。比如说,我们想把两个结构体相加,那肯定是不能直接做到的。更常见的情况是排序,如果使用sort对结构体排序,一般必须使用cmp。但c++为我们提供了一个解决方法:运算符重载

格式如下:

返回类型 operator 运算符名称(形参列表){
        重载实体;
}

注:结构体内外都可以定义,但结构体外定义需要多加一个形参:const 结构体类型名称& 结构体类型变量名,如:const node& a

单纯看这个可能看不懂,下边来看一组示例:

#include<iostream>
using namespace std;
struct node{
    int x,y;
    node operator + (const node& tmp){
        node res;
        res.x=x+tmp.x;
        res.y=y+tmp.y;
        return res;
    }
};
int main(){
    node a{1,2},b{3,4};
    node ans=a+b;
    cout<<ans.x<<" "<<ans.y<<endl;
    return 0;
}

输出:

4 6

运算符重载更常用的范围是排序:

#include<iostream>
#include<algorithm>
using namespace std;
struct node{
    int x,y;
    bool operator < (const node& t){
        if(x==t.x){
            return y<t.y;
        }
        return x<t.x;
    }
}r[12];
int main(){
    for(int i=1;i<=10;i++){
        cin>>r[i].x>>r[i].y;
    }
    sort(r+1,r+10);
    for(int i=1;i<=10;i++){
        cout<<r[i].x<<" "<<r[i].y<<endl;
    }
    return 0;
}

输入:

1 2
5 2
4 5
2 8
1 3
1 5
1 4
2 9
3 4
5 4

 输出:

1 2
1 3
1 4
1 5
2 8
2 9
3 4
4 5
5 2
5 4
 

 2.随机数生成

常用于竞赛中的对拍。

①rand()

范围:1~32767

使用方法:

取范围[n,m]的数,写法为 rand()%(m-n+1)+n

#include<iostream>
#include<ctime>
using namespace std;
int main(){
    srand(unsigned(time(0)));
    int count1=rand()%3+1;  //范围:1~3
    int count2=rand()%3;    //范围:0~2
    cout<<count1<<endl<<count2;
    return 0;
}

②mt19937()

范围:无限制,可自己设定

使用方法:

无限制:

#include<iostream>
#include<chrono>
#include<random>
using namespace std;
int main(){
    //随机数种子
    unsigned seed=std::chrono::system_clock::now().time_since_epoch().count();
    mt19937 rand_num(seed);  //大随机数
    cout<<rand_num()<<endl;
    return 0;
}

手动设定范围:

#include<iostream>
#include<chrono>
#include<random>
using namespace std;
int main(){
    //随机数种子
    unsigned seed=std::chrono::system_clock::now().time_since_epoch().count();
    mt19937 rand_num(seed);  //大随机数
    uniform_int_distribution<long long> dist(0,1000000);//给定范围:0~1000000
    cout<<dist(rand_num)<<endl;
    return 0;
}

可以看出,mt19937()使用起来非常麻烦,因此建议用多个rand()函数的结果相乘,也可以生成较大的随机数,且使用起来非常简便。

二、STL库函数

1.algorithm

头文件:<algorithm>

用法1:排序(sort

默认从小到大排序,如有其他需要可自行添加比较函数(cmp

例(从大到小):

#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,7,4};
bool cmp(int a,int b){
    return a>b;
}
int main(){
    sort(a,a+6,cmp);
    for(int i=0;i<6;i++){
        cout<<a[i]<<" ";
    }
    return 0;
}

输出:

7 5 4 3 2 1

用法2:去重(unique

可以将有序数据中的重复元素去除

例:

#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,5,2};
int main(){
    sort(a,a+6);
    int len=unique(a,a+6)-a;
    cout<<len<<endl;
    for(int i=0;i<len;i++){
        cout<<a[i]<<" ";
    }
    return 0;
}

输出:

4

1 2 3 5

用法3:二分查找(lower_bound、upper_bound) 

二分查找有序数据中的元素

例:

#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,5,2};
int main(){
    /*
    二分查找num的位置
    lower_bound是查找第一个大于等于num的位置
    upper_bound是查找第一个大于num的位置,如果不存在就返回最后一个元素的后一位
    */
    sort(a,a+6);
    int num=3;
	int x=lower_bound(a,a+6,num)-a;
    int y=upper_bound(a,a+6,num)-a;
    cout<<x<<" "<<y;
    return 0;
}

输出:

3 4

用法4:全排列(next_permutation、prev_permutation

有序数据进行全排列

例:

#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,5,2};
int main(){
    /*
    next_permutation:求下一个全排列
    */
    sort(a,a+6);
    do{
        for(int i=0;i<6;i++){
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }while(next_permutation(a,a+6));
    return 0;
}

 输出:

1 2 2 3 5 5 
1 2 2 5 3 5 
1 2 2 5 5 3 
1 2 3 2 5 5 
1 2 3 5 2 5 
1 2 3 5 5 2 
1 2 5 2 3 5 
1 2 5 2 5 3 
1 2 5 3 2 5 
1 2 5 3 5 2 
1 2 5 5 2 3 
1 2 5 5 3 2 
1 3 2 2 5 5 
1 3 2 5 2 5 
1 3 2 5 5 2 
1 3 5 2 2 5 
1 3 5 2 5 2 
1 3 5 5 2 2 
1 5 2 2 3 5 
1 5 2 2 5 3 
1 5 2 3 2 5 
1 5 2 3 5 2 
1 5 2 5 2 3 
1 5 2 5 3 2 
1 5 3 2 2 5 
1 5 3 2 5 2 
1 5 3 5 2 2 
1 5 5 2 2 3 
1 5 5 2 3 2 
1 5 5 3 2 2 
2 1 2 3 5 5 
2 1 2 5 3 5 
2 1 2 5 5 3 
2 1 3 2 5 5 
2 1 3 5 2 5 
2 1 3 5 5 2 
2 1 5 2 3 5 
2 1 5 2 5 3 
2 1 5 3 2 5 
2 1 5 3 5 2 
2 1 5 5 2 3 
2 1 5 5 3 2 
2 2 1 3 5 5 
2 2 1 5 3 5 
2 2 1 5 5 3 
2 2 3 1 5 5 
2 2 3 5 1 5 
2 2 3 5 5 1 
2 2 5 1 3 5 
2 2 5 1 5 3 
2 2 5 3 1 5 
2 2 5 3 5 1 
2 2 5 5 1 3 
2 2 5 5 3 1 
2 3 1 2 5 5 
2 3 1 5 2 5 
2 3 1 5 5 2 
2 3 2 1 5 5 
2 3 2 5 1 5 
2 3 2 5 5 1 
2 3 5 1 2 5 
2 3 5 1 5 2 
2 3 5 2 1 5 
2 3 5 2 5 1 
2 3 5 5 1 2 
2 3 5 5 2 1 
2 5 1 2 3 5 
2 5 1 2 5 3 
2 5 1 3 2 5 
2 5 1 3 5 2 
2 5 1 5 2 3 
2 5 1 5 3 2 
2 5 2 1 3 5 
2 5 2 1 5 3 
2 5 2 3 1 5 
2 5 2 3 5 1 
2 5 2 5 1 3 
2 5 2 5 3 1 
2 5 3 1 2 5 
2 5 3 1 5 2 
2 5 3 2 1 5 
2 5 3 2 5 1 
2 5 3 5 1 2 
2 5 3 5 2 1 
2 5 5 1 2 3 
2 5 5 1 3 2 
2 5 5 2 1 3 
2 5 5 2 3 1 
2 5 5 3 1 2 
2 5 5 3 2 1 
3 1 2 2 5 5 
3 1 2 5 2 5 
3 1 2 5 5 2 
3 1 5 2 2 5 
3 1 5 2 5 2 
3 1 5 5 2 2 
3 2 1 2 5 5 
3 2 1 5 2 5 
3 2 1 5 5 2 
3 2 2 1 5 5 
3 2 2 5 1 5 
3 2 2 5 5 1 
3 2 5 1 2 5 
3 2 5 1 5 2 
3 2 5 2 1 5 
3 2 5 2 5 1 
3 2 5 5 1 2 
3 2 5 5 2 1 
3 5 1 2 2 5 
3 5 1 2 5 2 
3 5 1 5 2 2 
3 5 2 1 2 5 
3 5 2 1 5 2 
3 5 2 2 1 5 
3 5 2 2 5 1 
3 5 2 5 1 2 
3 5 2 5 2 1 
3 5 5 1 2 2 
3 5 5 2 1 2 
3 5 5 2 2 1 
5 1 2 2 3 5 
5 1 2 2 5 3 
5 1 2 3 2 5 
5 1 2 3 5 2 
5 1 2 5 2 3 
5 1 2 5 3 2 
5 1 3 2 2 5 
5 1 3 2 5 2 
5 1 3 5 2 2 
5 1 5 2 2 3 
5 1 5 2 3 2 
5 1 5 3 2 2 
5 2 1 2 3 5 
5 2 1 2 5 3 
5 2 1 3 2 5 
5 2 1 3 5 2 
5 2 1 5 2 3 
5 2 1 5 3 2 
5 2 2 1 3 5 
5 2 2 1 5 3 
5 2 2 3 1 5 
5 2 2 3 5 1 
5 2 2 5 1 3 
5 2 2 5 3 1 
5 2 3 1 2 5 
5 2 3 1 5 2 
5 2 3 2 1 5 
5 2 3 2 5 1 
5 2 3 5 1 2 
5 2 3 5 2 1 
5 2 5 1 2 3 
5 2 5 1 3 2 
5 2 5 2 1 3 
5 2 5 2 3 1 
5 2 5 3 1 2 
5 2 5 3 2 1 
5 3 1 2 2 5 
5 3 1 2 5 2 
5 3 1 5 2 2 
5 3 2 1 2 5 
5 3 2 1 5 2 
5 3 2 2 1 5 
5 3 2 2 5 1 
5 3 2 5 1 2 
5 3 2 5 2 1 
5 3 5 1 2 2 
5 3 5 2 1 2 
5 3 5 2 2 1 
5 5 1 2 2 3 
5 5 1 2 3 2 
5 5 1 3 2 2 
5 5 2 1 2 3 
5 5 2 1 3 2 
5 5 2 2 1 3 
5 5 2 2 3 1 
5 5 2 3 1 2 
5 5 2 3 2 1 
5 5 3 1 2 2 
5 5 3 2 1 2 
5 5 3 2 2 1 
 

#include<iostream>
#include<algorithm>
using namespace std;
int a[]={1,5,3,2,5,2};
bool cmp(int a,int b){
    return a>b;
}
int main(){
    /*
    prev_permutation:求上一个全排列
    */
    sort(a,a+6,cmp);
    do{
        for(int i=0;i<6;i++){
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }while(prev_permutation(a,a+6));
    return 0;
}

输出:

5 5 3 2 2 1 
5 5 3 2 1 2 
5 5 3 1 2 2 
5 5 2 3 2 1 
5 5 2 3 1 2 
5 5 2 2 3 1 
5 5 2 2 1 3 
5 5 2 1 3 2 
5 5 2 1 2 3 
5 5 1 3 2 2 
5 5 1 2 3 2 
5 5 1 2 2 3 
5 3 5 2 2 1 
5 3 5 2 1 2 
5 3 5 1 2 2 
5 3 2 5 2 1 
5 3 2 5 1 2 
5 3 2 2 5 1 
5 3 2 2 1 5 
5 3 2 1 5 2 
5 3 2 1 2 5 
5 3 1 5 2 2 
5 3 1 2 5 2 
5 3 1 2 2 5 
5 2 5 3 2 1 
5 2 5 3 1 2 
5 2 5 2 3 1 
5 2 5 2 1 3 
5 2 5 1 3 2 
5 2 5 1 2 3 
5 2 3 5 2 1 
5 2 3 5 1 2 
5 2 3 2 5 1 
5 2 3 2 1 5 
5 2 3 1 5 2 
5 2 3 1 2 5 
5 2 2 5 3 1 
5 2 2 5 1 3 
5 2 2 3 5 1 
5 2 2 3 1 5 
5 2 2 1 5 3 
5 2 2 1 3 5 
5 2 1 5 3 2 
5 2 1 5 2 3 
5 2 1 3 5 2 
5 2 1 3 2 5 
5 2 1 2 5 3 
5 2 1 2 3 5 
5 1 5 3 2 2 
5 1 5 2 3 2 
5 1 5 2 2 3 
5 1 3 5 2 2 
5 1 3 2 5 2 
5 1 3 2 2 5 
5 1 2 5 3 2 
5 1 2 5 2 3 
5 1 2 3 5 2 
5 1 2 3 2 5 
5 1 2 2 5 3 
5 1 2 2 3 5 
3 5 5 2 2 1 
3 5 5 2 1 2 
3 5 5 1 2 2 
3 5 2 5 2 1 
3 5 2 5 1 2 
3 5 2 2 5 1 
3 5 2 2 1 5 
3 5 2 1 5 2 
3 5 2 1 2 5 
3 5 1 5 2 2 
3 5 1 2 5 2 
3 5 1 2 2 5 
3 2 5 5 2 1 
3 2 5 5 1 2 
3 2 5 2 5 1 
3 2 5 2 1 5 
3 2 5 1 5 2 
3 2 5 1 2 5 
3 2 2 5 5 1 
3 2 2 5 1 5 
3 2 2 1 5 5 
3 2 1 5 5 2 
3 2 1 5 2 5 
3 2 1 2 5 5 
3 1 5 5 2 2 
3 1 5 2 5 2 
3 1 5 2 2 5 
3 1 2 5 5 2 
3 1 2 5 2 5 
3 1 2 2 5 5 
2 5 5 3 2 1 
2 5 5 3 1 2 
2 5 5 2 3 1 
2 5 5 2 1 3 
2 5 5 1 3 2 
2 5 5 1 2 3 
2 5 3 5 2 1 
2 5 3 5 1 2 
2 5 3 2 5 1 
2 5 3 2 1 5 
2 5 3 1 5 2 
2 5 3 1 2 5 
2 5 2 5 3 1 
2 5 2 5 1 3 
2 5 2 3 5 1 
2 5 2 3 1 5 
2 5 2 1 5 3 
2 5 2 1 3 5 
2 5 1 5 3 2 
2 5 1 5 2 3 
2 5 1 3 5 2 
2 5 1 3 2 5 
2 5 1 2 5 3 
2 5 1 2 3 5 
2 3 5 5 2 1 
2 3 5 5 1 2 
2 3 5 2 5 1 
2 3 5 2 1 5 
2 3 5 1 5 2 
2 3 5 1 2 5 
2 3 2 5 5 1 
2 3 2 5 1 5 
2 3 2 1 5 5 
2 3 1 5 5 2 
2 3 1 5 2 5 
2 3 1 2 5 5 
2 2 5 5 3 1 
2 2 5 5 1 3 
2 2 5 3 5 1 
2 2 5 3 1 5 
2 2 5 1 5 3 
2 2 5 1 3 5 
2 2 3 5 5 1 
2 2 3 5 1 5 
2 2 3 1 5 5 
2 2 1 5 5 3 
2 2 1 5 3 5 
2 2 1 3 5 5 
2 1 5 5 3 2 
2 1 5 5 2 3 
2 1 5 3 5 2 
2 1 5 3 2 5 
2 1 5 2 5 3 
2 1 5 2 3 5 
2 1 3 5 5 2 
2 1 3 5 2 5 
2 1 3 2 5 5 
2 1 2 5 5 3 
2 1 2 5 3 5 
2 1 2 3 5 5 
1 5 5 3 2 2 
1 5 5 2 3 2 
1 5 5 2 2 3 
1 5 3 5 2 2 
1 5 3 2 5 2 
1 5 3 2 2 5 
1 5 2 5 3 2 
1 5 2 5 2 3 
1 5 2 3 5 2 
1 5 2 3 2 5 
1 5 2 2 5 3 
1 5 2 2 3 5 
1 3 5 5 2 2 
1 3 5 2 5 2 
1 3 5 2 2 5 
1 3 2 5 5 2 
1 3 2 5 2 5 
1 3 2 2 5 5 
1 2 5 5 3 2 
1 2 5 5 2 3 
1 2 5 3 5 2 
1 2 5 3 2 5 
1 2 5 2 5 3 
1 2 5 2 3 5 
1 2 3 5 5 2 
1 2 3 5 2 5 
1 2 3 2 5 5 
1 2 2 5 5 3 
1 2 2 5 3 5 
1 2 2 3 5 5 
 

用法 5:最大、最小(maxmin


查找最大、最小

例:

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    /*
    max(a,b)查找a和b的最大值
    min(a,b)查找a和b的最小值
    */
    int a=1,b=2;
    cout<<max(a,b)<<endl;
    cout<<min(a,b);
    return 0;
}

输出:

2

1

用法6:交换(swap


交换两个变量的值。 

例:

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    /*
    swap(a,b)交换a和b的值
    */
    int a=1,b=2;
    swap(a,b);
    cout<<a<<" "<<b;
    return 0;
}

用法7:查找(find) 

查找一个元素的位置。

例:

#include<iostream>
#include<algorithm>
using namespace std;
int a[]={3,1,4,1,7,9};
int main(){
    /*
    find(begin,end,value);
    返回区间中第一个元素值等于 value 的元素位置。
    find_if(begin,end,op);
    返回区间中第一个满足“op(elem)==true”的元素位置。
    如果没有找到匹配元素,则返回所传入的 end,不是 NULL!
    */
    int ans=find(a,a+6,7)-a;
    cout<<ans;
    return 0;
}

输出:

2.stack(栈)

头文件<stack>

stack(栈)是 STL 实现的栈容器,可以实现栈的基本操作

以下所有操作时间复杂度为O(1)

stack<int> stk;常用函数功能
stk.push(x);将x入栈

stk.top();

获取栈顶元素
stk.pop();弹出栈顶元素
stk.empty();

判断栈是否为空

空返回true,不空返回false

stk.size();返回栈内元素个数

括号匹配

时间限制:1秒        内存限制:128M

题目描述

假设表达式中允许包含圆括号和方括号两种括号,其嵌套的顺序随意,如([]())或[([][])]等为正确的匹配,[(])或([]()或(()))均为错误的匹配 

本题的任务是检验一个给定的表达式中的括号是否匹配正确 

输入一个只包含圆括号和方括号的字符串,判断字符串中的括号是否匹配,匹配就输出“OK”,不匹配就输出“Wrong”

输入描述

一行字符,只含有圆括号和方括号,个数小于255

输出描述

匹配就输出一行文本“OK“,不匹配就输出一行文本”Wrong”

样例

输入

[(])

输出

Wrong

#include<iostream>
#include<stack>
using namespace std;
stack<char> stk;
bool check(string s){
    stk.push('#');
    for(int i=0;i<s.size();i++){
        char c=s[i];
        if(c==')'){
            if(stk.top()=='('){
                stk.pop();
            }
            else{
                return false;
            }
        }
        else if(c==']'){
            if(stk.top()=='['){
                stk.pop();
            }
            else{
                return false;
            }
        }
        else{
            stk.push(c);
        }
    }
    return stk.size()==1;
}
int main(){
    string s;
    cin>>s;
    if(check(s)){
        cout<<"OK";
    }
    else{
        cout<<"Wrong";
    }
    return 0;
}

 3.queue(队列)

头文件<queue>

queue(队列)是 STL 实现的队列容器,可以实现队列的基本操作

以下所有操作时间复杂度为O(1)

queue<int> q;常用函数操作
q.push(x);将x入队
q.front(),q.back()front()返回队首,back()返回队尾
q.pop();队首元素出队
q.empty();

判断队是否为空

空返回true,不空返回false

q.size();返回队内元素个数

priority_queue(优先队列)

头文件<queue>

优先队列,底层实现是堆,可将压入队内的元素自动排序

定义方法:
priority_queue<int>q; //默认降序优先队列
priority_queue<int, vector<int>, greater<int> >q; //升序优先队列
priority_queue<int, vector<int>, less<int> >q; //降序优先队列

priority_queue<int> q;常用函数操作
q.push(x);将x入队
q.top();返回队首元素
q.pop();队首元素出队
q.empty();

判断队是否为空

空返回true,不空返回false

q.size();返回队内元素个数

可插入运算符重载后的结构体或pair

deque(双端队列)

头文件<deque>

双端队列,队列两端都可以出队或入队

deque<int> q;常用函数操作
q.push_front(x);将x从队首入队
q.push_back(x);将x从队尾入队
q.front();返回队首元素
q.back();返回队尾元素
q.pop_front();队首元素出队
q.pop_back();队尾元素出队
q.empty();

判断队是否为空

空返回true,不空返回false

q.size();返回队内元素个数

周末舞会

时间限制:1秒        内存限制:128M

题目描述

假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴。规定每个舞曲能有一对跳舞者。若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲。现要求写一个程序,模拟上述舞伴配对问题。(0<m,n,k<1000)

输入描述

第一行男士人数m和女士人数n;
第二行舞曲的数目k。

输出描述

共k行,每行两个数,表示配对舞伴的序号,男士在前,女士在后。

样例

输入

2 4
6

输出

1 1
2 2
1 3
2 4
1 1
2 2

提示

显然,舞伴配对的顺序符合“先进先出”,所以用两个队列分别存放男士队伍和女士队伍,然后模拟k次配对:每次取各队队头元素“配对”输出,并进行“出队”和重新“入队”的操作

#include<iostream>
#include<queue>
using namespace std;
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    queue<int> q1,q2;
    for(int i=1;i<=n;i++){
        q1.push(i);
    }
    for(int i=1;i<=m;i++){
        q2.push(i);
    }
    for(int i=1;i<=k;i++){
        cout<<q1.front()<<" "<<q2.front()<<endl;
        q1.push(q1.front());
        q1.pop();
        q2.push(q2.front());
        q2.pop();
    }
    return 0;
}

合并果子

时间限制:1秒        内存限制:128M

题目描述

        在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。          因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。          例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。 

输入描述

        输入包括两行,第一行是一个整数n(1< =n< =10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1< =ai< =20000)是第i种果子的数目。 

输出描述

        输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于2^31。 

样例

输入

3 
1 2 9 

输出

15

提示

对于30%的数据,保证有n< =1000:  对于50%的数据,保证有n< =5000;  对于全部的数据,保证有n< =10000。 

#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> >q;
int n,x,ans;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x;
        q.push(x);
    }
    while(q.size()>=2){
        int a=q.top();
        q.pop();
        int b=q.top();
        q.pop();
        ans+=(a+b);
        q.push(a+b);
    }
    cout<<ans;
    return 0;
}

4.vector(向量)

头文件<vector>

本质是一个动态大小的数组,可存放任意类型的对象。

操作及时间复杂度:

vector<int> a(10); 

定义了 10 个整型元素的向量

(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的

O(n)
vector<int> a(10,1); 定义了 10 个整型元素的向量,且元素的初值都为 1O(n)
vector<int> a(b); 用 b 向量来创建 a 向量,整体复制性赋值O(n)
vector<int>a(b.begin(),b.begin+3);a 的初值为向量 b 的前三个值O(n)

int b[7]={1,2,3,4,5,9,8};

vector<int> a(b,b+7);

从数组中获得初值O(n)
v[i];以下标方式访问元素O(1)
v.push_back(x);往尾部插入元素 x (常用)O(1)
v.insert(it, x); 向迭代器 it 指向的位置插入 x,原位置后移O(n)
v.size();返回表长,注意是 unsigned 类型O(1)
v.front();取首元素的值O(1)
v.back();取尾元素的值O(1)
v.empty(); 表为空返回true,否则返回falseO(1)
v.clear();清空表O(1)
v.pop_back();删除表尾元素O(1)
v.erase(it);删除迭代器 it 指向的元素O(n)

vector迭代器

类似于指针,用于访问元素

例:

vector<int>::iterator it;
for(it=v.begin();it!=v.end();it++){  //begin()表示首元素位置,end()表尾元素位置
    cout<<*it<<endl;
}

5.map(映射)

头文件<map>

可以简单理解为下标可以是任何类型的数组,可用于解释函数

操作:

m.find(x)查找x是否存在
m.count(x)键为 x 的数量(等同于查找 x 是否存在)
m.empty()判断是否为空
m.size()返回容器内元素数量
m.insert(x)

插入x,x 必须为对的形式。

可以为 pair 的形式,通过 make_pair 创建。

m.erase(x)将键值为 x 的元素删除。
m.clear()清空 map

map 的底层是红黑树,所以查找、插入、删除、访问的时间复杂度都是 log 级。

map迭代器

vector迭代器类似,有以下区别:

  1. map是有序的,根据第一关键字自动排序
  2. map迭代器取值不用*,而用 ->first 取第一关键字, ->second 取第二关键字
  3. map 的迭代器只能++,--,不能+-数值

unordered_map
头文件<unordered_map

map几乎完全一样,区别在于unordered_map是无序的其操作速度比map稍快一点。

multimap
头文件<map>

同样与map几乎完全一样,但可以保存重复元素。

查字典

时间限制:1秒        内存限制:128M

题目描述

全国英语四级考试就这样如期到来了,可是小Y依然没有做好充分的准备。为了能够大学毕业,可怜的小Y决定作弊。(太胆大妄为了,不怕被学校开除!!)

 小Y费尽心机,在考试的时候夹带了一本字典进考场。但是现在的问题是,考试的时候可能有很多单词要查,小Y能不能来得及呢。

输入描述

第一行一个整数N,表示字典中一共有多少单词(N<=10000)。 

接下来每两行表示一个单词,其中: 第一行是一个长度<=100的字符串,表示这个单词,全部小写字母,单词不会重复。 

第二行是一个整数,表示这个单词在字典中的页码。 

接下来一行是一个整数M,表示要查的单词数(M<=10000)。 

接下来M行,每行一个字符串,表示要查的单词,保证在字典中存在。

输出描述

M行,每行一个整数,表示第i个单词在字典中的页数。

样例

输入

2
scan
10
word
15
2
scan
word

输出

10
15
#include<iostream>
#include<map>
using namespace std;
int main(){
    map<string,int> m;
    int n;
    cin>>n;
    string t;
    for(int i=0;i<n;i++){
        cin>>t;
        cin>>m[t];
    }
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>t;
        cout<<m[t]<<endl;
    }
    return 0;
}

 6.set(集合)

头文件<set>

去重,可以自动升序排序

set<T> s;常用函数操作
s.insert(x);插入x
s.erase(x);删除x
s.count(x);查找x,存在返回1,不存在返回0
s.clear();清空

unordered_set
头文件<unordered_set>

和set类似,去重但无序。

multiset
头文件<set>

和set类似,有序但不去重。

集合的并

时间限制:1秒        内存限制:128M

题目描述

现在有两个集合,计算两个集合的并,即{A}+{B}。

注:{A}+{B}中不允许出现重复元素,但是{A}与{B}之间可能存在相同元素。

输入描述

多组测试数据。

每组数据包含三行。

第一行为两个正整数n,m。分别表示两个集合的元素数量。

第二行为第一个集合元素、第三行为第二个集合元素。

输出描述

输出两个集合并后的元素。

样例

输入

1 2
1
2 3
1 2
1
1 2

输出

1 2 3
1 2

提示

A集合与B集合内部元素可能会出现重复。

n,m不超过10000.

集合内元素最大不超过int的最大值。

#include<iostream>
#include<set>
using namespace std;
set<int> se;
int main(){
    int n,m,x;
    while(cin>>n>>m){
        se.clear();
        for(int i=1;i<=n;i++){
            cin>>x;
            se.insert(x);
        }
        for(int i=1;i<=m;i++){
            cin>>x;
            se.insert(x);
        }
        while((int)se.size()){
            cout<<*se.begin()<<" ";
            se.erase(se.begin());
        }
        cout<<endl;
    }
    return 0;
}

 7.memset(填充)

头文件<cstring>

格式:memset(数组名,值,sizeof(数组名));

作用:将数组全部赋值。

注意:建议赋值时只赋值0,-1,0x3f.

8.pair(对)

包含两个数据值,两数据类型可不同。

初始化:pair<类型1,类型2> 名称

可在定义时直接赋值,如pair<string,string> a("CS","DN");x

用法:第一个元素为a.first,第二个元素为b.second.

用已有的两个元素生成pair,可用make_pair(),如make_pair(1,"CSDN");

9.万能头文件

#include<bits/stdc++.h>

一个几乎万能的头文件,包含所有可用到的C++库函数。

优点:

节约时间,减少工作量。

缺点:

增加编译时间,个别在线评测系统不兼容。

--------------------------------------------end--------------------------------------------

ps:后续还可能会不断完善,感谢支持! 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值