• 寒假训练——第一周(STL)



    前言:

    本篇设计 S T L STL STL 中的 栈 ( A , B ) (A, B) (A,B) ,优先队列 ( C ) (C) (C) ,以及 b i t s e t bitset bitset ( D ) (D) (D)


    A - 只有一端开口的瓶子

    A - 只有一端开口的瓶子

    思路:

    若两个栈,则可以将所有序列按照顺序弹出;

    1 − > 2 , 2 − > 1 1 - > 2, 2 -> 1 1>2,2>1 互相弹出,直到现在需要的数则弹出到序列末端

    如此只需判断是否需要两个栈即可:

    我们每插入一个数时判断能否弹出到序列中,最后如果栈中剩下数,则一个栈无法完成该操作,输出两个栈为答案。

    代码如下:

    #include 
    
    #define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
    
    #define x first
    #define y second
    #define int long long
    
    using namespace std;
    
    typedef pair<int, int> PII;
    
    const int N = 4050, M = 16000057 * 2, null = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int n, m;
    stack<int> stk;
    
    void solve()
    {
        cin >> n;
        
        while (stk.size()) stk.pop();
        
        int res = 1;
        int t = 1;
        int x;
        for (int i = 1; i <= n; i ++ )
        {
            cin >> x;
            stk.push(x);
            while(stk.size() && stk.top() == t) stk.pop(), t ++;
        }
        
        if(stk.size()) res = 2;
        
        cout << res << endl;
    }
    
    signed main()
    {
        fast;
        int T;
        cin >> T;
        while (T -- )
            solve();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    B - 火车快跑

    B - 火车快跑

    思路:

    出栈序列为输入的序列,入栈序列为 1 1 1 -> n n n

    每入栈一次,判断能否按照出栈序列出栈,若可以则接着判断,直到所有火车都入栈,且判断玩出栈顺序,若栈中仍有火车,则该出栈顺序不合法

    代码如下:

    #include 
    
    #define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
    
    #define x first
    #define y second
    #define int long long
    
    using namespace std;
    
    typedef pair<int, int> PII;
    
    const int N = 4050, M = 16000057 * 2, null = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int n, m;
    int a[N];
    stack<int> stk;
    
    signed main()
    {
        fast;
        while (cin >> n)
        {
            while (stk.size()) stk.pop();
            
            for (int i = 1; i <= n; i ++ )
                cin >> a[i];
            
            int t = 1;
            
            for (int i = 1; i <= n; i ++ )
            {
                stk.push(i);
                while(stk.size() && stk.top() == a[t]) stk.pop(), t ++;
            }
            
            if(stk.size()) cout << "No" << endl;
            else cout << "Yes" << endl;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    C - Prefix K-th Max

    C - Prefix K-th Max

    思路:

    如果插入一次 s o r t sort sort 一次会 T L E TLE TLE

    可以利用 S T L STL STL 中的优先队列(此处指小根堆):

    • 如果优先队列中保持 k k k 个数,则其队头即为所求值
    • 时间复杂度为 O ( l o g k ) O(logk) O(logk)

    则算法总复杂度为 O ( ( n − k + 1 ) ∗ ( l o g k ) ) O( (n-k+1) * (logk) ) O((nk+1)(logk))

    当队列中已经有 k 个数时,如何使优先队列中保持 k k k 个数 ?

    • 先插入一个数
    • 弹出队头,输出队头

    解释 步骤 2 :

    • 判断该数与原队头的关系
    • 若大于 原队头 则弹出现队头(即、此数);若该数小于 原队头 则弹出现队头(现队头为 k + 1 k+1 k+1小的数,无价值);若 等于 则弹出
    • 发现无论大于小于等于都是先弹出队头,再输出队头

    如此得出结论!

    代码如下:

    #include 
    
    #define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
    
    #define x first
    #define y second
    #define int long long
    
    using namespace std;
    
    typedef pair<int, int> PII;
    
    const int N = 5000010, M = 16000057 * 2, null = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int n, m;
    int a[N];
    priority_queue<int, vector<int>, greater<int>> heap;
    
    signed main()
    {
        fast;
        
        cin >> n >> m;
        
        int x;
        for (int i = 1; i <= n; i ++ )
        {
            cin >> x;
            heap.push(x);
            if(i == m) cout << heap.top() << endl;
            else if(i > m)
            {
                heap.pop();
                cout << heap.top() << endl;
            }
        }
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    D - 简单瞎搞题

    D - 简单瞎搞题

    思路: b i t s e t bitset bitset + D P DP DP

    D P DP DP 思路:
    f [ i ] [ j ] f[i][j] f[i][j] 表示:已经取了前 i i i 个区间后答案为 j j j 的个数

    状态转移方程为:f[i][j] += f[i-1][j - k*k]


    D P DP DP T L E TLE TLE 代码如下:

    时间复杂度: O ( n ∗ n ∗ m ) O(n*n*m) O(nnm) 其中: n = 100 , m = 10 0 3 n = 100, m = 100 ^ 3 n=100,m=1003

    signed main()
    {
        fast;
        
        cin >> n;
        
        f[0][0] = 1;
        int l, r;
        for (int i = 1; i <= n; i ++ )
        {
            cin >> l >> r;
            for (int j = 1; j <= M; j ++ )
                for (int k = l; k <= r; k ++ )
                    if(j >= k * k) f[i][j] += f[i - 1][j - k * k];
        }
        
        int res = 0;
        for (int i = 1; i <= M; i ++ )
            if(f[n][i]) res ++ ;
        
        cout << res << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    定义一个 b i t s e t bitset bitset d p [ 110 ] dp[110] dp[110]

    • d p [ i ] dp[i] dp[i] 的一位代表 f [ i ] [ j ] f[i][j] f[i][j] j j j 位置不为空!
    • 即、存在 f [ i ] [ j ] f[i][j] f[i][j] 这种情况 r e s res res ++
    • 如此结果即为 d p [ n ] dp[n] dp[n] 1 1 1 的个数

    即用 b i t s e t bitset bitset 数组 d p [ N ] dp[N] dp[N] 等效替换 上述代码的 d p [ N ] [ M ] dp[N][M] dp[N][M]

    下面代码采用循环数组做的:

    b i t s e t bitset bitset A C AC AC 代码如下:

    #include 
    
    #define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
    
    #define x first
    #define y second
    #define int long long
    
    using namespace std;
    
    typedef pair<int, int> PII;
    
    const int N = 110, M = 1000010, null = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int n, m;
    int f[N][M];
    bitset<M> dp, t; // 0000001000
    
    signed main()
    {
        fast;
        
        cin >> n;
        
        dp = 1;
        int l, r;
        for (int i = 1; i <= n; i ++ )
        {
            cin >> l >> r;
            
            t.reset();
            for (int k = l; k <= r; k ++ )
                t |= (dp << k * k); 
                // dp[i] + 比 k * k 大的所有情况
                // 等效于 for (int j = k * k; j <= M; j ++ )
                //            dp[i][j] += dp[i-1][j - k * k]
                
            dp = t;
        }
        
        cout << dp.count() << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
  • 相关阅读:
    helm kubernetes包管理工具
    Ubuntu:VS Code IDE安装ESP-IDF【保姆级】
    excel筛选后求和
    基因型数据VCF转EXCEL亲测好用
    谁能想到先打败程序员的不是35岁,而是.
    JVM监控工具jstat使用介绍
    我与梅西粉丝们的世界杯观球日常
    extern “C“的用法
    网格大师如何把b3dm转为osgb格式?
    Android Studio 中AGP ,Gradle ,JDK,SDK都是什么?
  • 原文地址:https://blog.csdn.net/m0_61409183/article/details/126370247