Codefores_Hello 2023

这应该说不上一篇题解博客,而是一个反省博客 

《B. MKnez's ConstructiveForces Task》

 这道题我要反省的是:毫无难度,直接按照条件推式子即可,但是我将奇,偶两种情况的推导搞混掉了,寄!

《C. Least Prefix Sum》

 

 

 这道题是我写的最久的,当时我是按照思维去想特殊情况,而没有用数学公式来分析,导致代码写的像答辩一样

很多细节都要考虑,十分复杂

其实这道题就是:

  要Sm<=Si(1<=i<=m-1)

    变化一下:Sm-Si<=0,即:S(i+1~m)<=0,(2<=i+1<=m)

    于是我们就可以用贪心的方式来维护S(i+1~m)<=0

    如果S(i+1~m)>0了,说明a[i+1]~a[m]有正数使得其这样,我们贪心地选这个区中最大的正数,然后反转他

  在Sm<=Si(m+1<=i<=n) 同理推导与贪心

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 2 * 1e5 + 2;
typedef long long ll;
int a[N];
ll p[N];
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, m, ans = 0;
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        // 判断没有前段的情况:即m==1时
        if (m != 1)
        {
            priority_queue<int, vector<int>, less<int>> heap;
            // 前段操作:即对1~m-1的操作
            p[m + 1] = 0;
            for (int i = m; i > 1; i--)
            {
                p[i] = p[i + 1] + a[i];
                if (a[i] > 0)
                    heap.push(a[i]);
                while (p[i] > 0)
                {
                    ll num = heap.top();
                    heap.pop();
                    p[i] -= 2 * num;
                    ans++;
                }
            }
        }
        // 后段操作:
        priority_queue<int, vector<int>, greater<int>> heap2;
        p[m] = 0;
        for (int i = m + 1; i <= n; i++)
        {
            p[i] = p[i - 1] + a[i];
            if (a[i] < 0)
                heap2.push(a[i]);
            while (p[i] < 0)
            {
                ll num = heap2.top();
                heap2.pop();
                p[i] -= 2 * num;
                ans++;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

 

《D. Boris and His Amazing Haircut》

 

 这道题其实我思路想到了,但是最后代码实现太复杂,实现不下去了,主要是因为我去代码模拟我的想法

 其实简单的实现就是用堆来实现:

  用堆来保存区间的数值,保证堆顶元素>新的区间元素,否则就要pop;

  这个操作正好是贪心地让每一个区间在l的值固定下,让r最大,直到这个区间不能再连续为止;

  

 

 

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <map>
 5 #include <stack>
 6 using namespace std;
 7 const int N = 2 * 1e5 + 2;
 8 int t, a[N], b[N], r[N];
 9 int main()
10 {
11     cin >> t;
12     while (t--)
13     {
14         int n;
15         cin >> n;
16         for (int i = 1; i <= n; i++)
17             scanf("%d", &a[i]);
18         bool flag = true;
19         for (int i = 1; i <= n; i++)
20         {
21             scanf("%d", &b[i]);
22             if (b[i] > a[i])
23                 flag = false;
24         }
25         int m;
26         cin >> m;
27         map<int, int> rn;
28         for (int i = 1; i <= m; i++)
29         {
30             scanf("%d", &r[i]);
31             rn[r[i]]++;
32         }
33         if (!flag)
34         {
35             cout << "NO" << endl;
36             continue;
37         }
38         stack<int> s;
39         for (int i = 1; i <= n; i++)
40         {
41             while (s.size() && s.top() < b[i])
42                 s.pop();
43             if (b[i] == a[i])
44                 continue;
45             if (s.size() == 0 || s.top() > b[i])
46             {
47                 if (rn[b[i]] <= 0)
48                 {
49                     flag = false;
50                     break;
51                 }
52                 rn[b[i]]--;
53                 s.push(b[i]);
54             }
55         }
56         if (flag)
57             cout << "YES" << endl;
58         else
59             cout << "NO" << endl;
60     }
61     return 0;
62 }

在写这道题的时候遇到了数组下标越界的情况,但是没报错,交上去真的啥问题都可能出现!

posted @ 2023-01-04 22:28  次林梦叶  阅读(36)  评论(0)    收藏  举报