zoukankan      html  css  js  c++  java
  • 2019 CCF夏令营 day 1

    来这里第一天表示非常的懵逼。然后发觉ckw讲的线性数据结构非常的难。

    关于栈和队列

    1.双端队列的用法

    deque <int> de;

    de.push_back(x);

    de.push_front(x);

    de.pop()_back;

    de.pop()_front;

    de.back();

    de.front();

    de.empty();

    2.关于括号序列的题

    这个题告诉我们考虑好||和&&的重要性。

    用栈存储右括号,遇左括号则出栈判断。

    #include <iostream>
    #include <cstdio>
    #include <stack>
    using namespace std;
    
    string s1;
    int len,xu;
    bool vis[109];
    stack < pair<char,int> > q;
    char now;
    
    int main(){
        cin>>s1;
        len=s1.size();
        for(int i=0;i<len;i++){
            if(s1[i]=='('||s1[i]=='[')
                q.push(make_pair(s1[i],i));
            else{
                if(!q.empty()){
                    now=q.top().first;
                    xu=q.top().second;
                }
                if(s1[i]==')'&&now=='('){
                    vis[i]=1;vis[xu]=1;q.pop();
                }
                if(s1[i]==']'&&now=='['){
                    vis[i]=1;vis[xu]=1;q.pop();
                }
            }
        }
        for(int i=0;i<len;i++){
            if(vis[i]==0){
                if(s1[i]=='('||s1[i]==')'){
                    printf("()");
                }
                if(s1[i]=='['||s1[i]==']'){
                    printf("[]");
                }
            }
            else printf("%c",s1[i]);
        }
        return 0;
    }
    View Code

    3.单调栈

    考虑这样一个问题:给你一列数字,对每个数字求出其右边第一个值大
    于等于它的数字的位置。要求做到线性。
    从右到左扫描整个序列,不能确定的则入栈,遇到比栈顶大的就一直出栈。直至不能再判断。(求最小时反向扫描)

    4.一个题

    有一列n个数字a[1]…a[n],对所有1<=L<=R<=n求
    max(a[L],a[L+1],…,a[R])并求和,n<=1e6。
     
    反向考虑,考虑一个数字最大能成为哪些区间的最大值。求出左面和右面比他大的数(反着扫一遍即可)(认为a[0]和a[n+1]是正无穷即可避免一些特判)一个小坑是遇见相等的数字时要钦定左面比右面大(例 1111111)
    5.另一个题
    考虑有一列n个数字,求1<=L<=R<=n使得(R-L+1)*min(a[L],a[L+1],…,a[R])最大。n<=1000000
    和上一个题一样的,求出来,比较,解法非常暴力。
    6.还有一个题
    有一个矩阵,每个位置是0或者1。求最大的全1子矩阵。n*m<=1000000。
    可以用前缀和来做,也可以扫描每一行,在每一行上向上求可达的 最小值。都是o(nm)。
     
    单调队列
    题曰滑动窗口,意思就是,比你小又比你厉害的会比你出场晚。
    问题是有一列数{a_n}和m个区间[L(i),R(i)],满足L(i)<=L(i+1),R(i)<=R(i+1)。对每个区间求区间最大值。
    比队列头头大的,把队列排空再入队;小的直接入队。o(n)
    链表
    没什么用。
     前缀和差分
    o(n)预处理,o(1)询问
    一维前缀和和二维前缀和。呃呃二维的比较难理解,
    求:b[x,y]=b[x-1,y]+b[x,y-1]-b[x-1,y-1]+a[x,y]
    矩阵求和:s(x1,y1,x2,y2)=b[x1-1,y1-1]+b[x2,y2]-b[x1-1,y2]+b[x2,y1-1]
    二维差分非常的神奇
    其实差分是前缀和的逆过程,可以由前缀和推过来。
    基数排序
    32768=2的15次方
    基数排序是一种桶排,比较普遍的是将数字的每一位拆开来,先按照末位排,在依次由低向高推进。或由高向低推进。也可以转换为二进制来桶排。
    STL
     
    #include <algorithm>
     
     stack,queue,deque,priority_queue,vector,set,map
    deque常数不小,不要用
    priority_queue是大根堆,小根堆可以插相反数或重载运算符。
     
    vector  不要对v.size()-1!因为这是一个unsigned int型的,对空的vector-1会得到一个INF
    关于v.resize()其复杂度是O(max(1, resize()中的参数-原来的size()))的

    v.clear()和vector<>().swap(v)的区别。
    • 前者是假装清空了,实际内存没有被回收。
    • 后者是真的回收了,不过需要和v.size()的大小成正比的时间

  • 相关阅读:
    ListBoxAddItems() 不重复添加Edit1
    Get_HD_Serial() 获得磁盘驱动器序列号
    JavaScript是否可实现多线程 — 深入理解JavaScript定时机制
    测测你是否近视!
    [趣闻]Google 员工架飞索去总部蹭饭
    datagridview回车事件
    抄过来的eGroupWare的一些资源
    DataGridView 添加ComboBox
    Chapter 1: Introducing the Project: TheBeerHouse
    Linux操作系统学习线路图
  • 原文地址:https://www.cnblogs.com/jindui/p/11272543.html
Copyright © 2011-2022 走看看