Codeforces Round 974 (Div. 3)A,B,C,D题解

目录

A. Robin Helps

B. Robin Hood and the Major Oak

C. Robin Hood in Town        

D. Robert Hood and Mrs Hood

先说一下这是我的第一篇题解,语言组织可能有点不妥。

A. Robin Helps

题目大意:

        英勇的亡命之徒罗宾汉以从富人那里拿走金钱并给予穷人而闻名。罗宾遇到n个人,从第1个人到第n个人。第i个人拥有ai金。如果ai≥k,罗宾将把所有的ai金拿走;如果ai=0,且罗宾有金的话,他将给予1金。罗宾开始时没有金。请找出罗宾将给予多少人金。

输入:

       第一行输入包含一个整数t (1≤t≤10^4) — 测试用例的数量。

        每个测试用例的第一行包含两个整数n, k (1≤n≤50, 1≤k≤100) — 人数和罗宾汉拿走金的阈值。

         每个测试用例的第二行包含n个整数a1, a2, …, an (0≤ai≤100) — 每个人的金。

输出:

        对于每个测试用例,输出一个整数,表示将从罗宾汉那里得到金的人数。

解题思路:

        循环模拟即可。

代码如下:
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin >> t;
    int w, n, k, ans, m;
    while (t--)
    {
        cin >> n >> k;
        w = 0;
        ans = 0;
        for (int i = 0; i < n; i++)
        {
            cin >> m;
            if (m >= k)
            {
                w += m;
            }
            if (m == 0 && w != 0)
            {
                w--;
                ans++;
            }
            
        }
        cout << ans << endl;
    }
}

B. Robin Hood and the Major Oak

题目大意:

Sherwood的Major Oak因其壮丽的树叶而闻名,这些树叶为罗宾汉和他的快乐伙伴们提供了庇护。

Major Oak在第i年生长出i片新叶。第1年开始时,它会在第1年有1片叶子。

叶子在树上会持续k年。换句话说,在第i年生长的叶子在第i年到第i+k−1年期间有效。

罗宾认为偶数是幸运的。帮助罗宾确定在第n年Major Oak会有偶数片叶子吗。

输入

        输入的第一行包含一个整数t (1≤t≤10^4) — 测试案例的数量。

        每个测试案例由两个整数n,k (1≤n≤10^9 ,1≤k≤n) — 请求的年份和叶子保持的年份组成。

输出

         对于每个测试案例,输出一行,如果在第n年Major Oak将有偶数片叶子,则输出“YES”,否则输出“NO”。

        你可以用任何大小写输出答案(大写或小写)。例如,“yEs”,“yes”,“Yes”,和“YES”都将被视为肯定的回答。

解题思路:

        叶子保存k年,就是只需要考虑n-k+1到n年的情况,这是个等差数列求和,公式如下         S_n= \frac{n}{2}\times \left ( a{1}+a{n} \right )

代码如下:
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
    int t;
    cin >> t;
    int w, n, k, ans, m;
    while (t--)
    {
        int n, k;
        cin >> n >> k;
        int w = n - k + 1;
        if (w < 1)
        {
            w = 1;
        }
        int sum = (n - w + 1) * (w + n) / 2;
        if (sum % 2 == 0)
        {
            cout << "YES" << endl;
        }
        else
        {
            cout << "NO" << endl;
        }
    }
}

C. Robin Hood in Town

题目大意:

环顾四周,富人越来越富,穷人越来越穷。我们需要从富人那里拿走一些财富,给穷人。我们需要罗宾汉!

在这个镇上住着 n 个人。现在,第 i 个人的财富是 a[i] 黄金。但是,你知道吗?最富有的人发现了一锅额外的黄金!

更正式地说,找出 a[j] = max(a[1], a[2], ..., a[n]),将 a[j] 改为 a[j] + x,其中 x 是锅中找到的非负整数黄金。如果有多个最大值,可以是其中任何一个。

如果一个人的财富严格低于平均财富的二分之一,他们就会感到不快乐。

如果超过一半的人口 n 都感到不快乐,罗宾汉将应公众的要求出现。

确定使罗宾汉出现所需的 x 的最小值,如果不可能,则输出 -1。

  • 平均财富定义为总财富除以总人口 n,即 ∑ a[i] / n,结果是一个实数。
输入:

        第一行输入一个整数 t (1 ≤ t ≤ 10^4) — 测试用例的数量。

        每个测试用例的第一行输入一个整数 n (1 ≤ n ≤ 2 · 10^5) — 总人口。

        每个测试用例的第二行输入 n 个整数 a[1], a[2], …, a[n] (1 ≤ a[i] ≤ 10^6) — 每个人的财富。

        可以保证,所有测试用例中 n 的总和不超过 2 · 10^5。

输出:

        对于每个测试用例,输出一个整数 — 最富有的人必须找到的黄金最小数量,以便罗宾汉出现。如果不可能,输出 -1。

解题思路:

        将每个人金子从小到大排序,找到刚刚好超过一半人的那个人,即第\frac{n+2}{2}个人,线下取整。

通过这个数,算出总和至少需要多少,最后x为需要总和-当前综合。

       

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define int long long
vector<int> a(2 * 100005);
signed main()
{
    int t;
    cin >> t;
    int w, n, k, ans, m;
    while (t--)
    {
        int n;
        cin >> n;
        int sum = 0;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            sum += a[i];
        }
        if (n <= 2)
        {
            cout << -1 << endl;
            continue;
        }
        sort(a.begin() + 1, a.begin() + n + 1);
        w=(n+2)/2;
        int x=a[w];
        x=x*n*2;
        ans=x+1-sum;
        if(ans<0){
            ans=0;
        }
        cout << ans << endl;
    }
}

D. Robert Hood and Mrs Hood

题目大意:

罗宾的兄弟和母亲正在拜访,而罗宾可以选择每位访客的开始日期。

所有的日子都被编号为1到n。访客会连续停留d天,所有这些d天必须在第1天到第n天之间(包括第1天和第n天)。

罗宾总共计划了k个有风险的“工作”。第i个工作发生在第li天到第ri天之间(包括第li天和第ri天),条件为1≤i≤k。如果一个工作在任何d天内进行,那么这次拜访就会与这个工作重叠(重叠的长度不重要)。

罗宾希望他兄弟的拜访能够与尽可能多的不同工作重叠,而他母亲的拜访则重叠的工作数量要尽量少。

找出罗宾的兄弟和母亲的合适开始日期。如果有多个合适的日期,选择最早的一个。

输入:

        第一行输入一个整数t(1≤t≤104)——测试用例的数量。

        每个测试用例的第一行包含三个整数n、d、k(1≤n≤105,1≤d,k≤n)——总天数、访客的停留天数和工作的数量。

        接下来的k行,每行包含两个整数li和ri(1≤li≤ri≤n)——每个工作的开始和结束天。

        保证所有测试用例中n的总和不超过2⋅105。

输出:

        对于每个测试用例,输出两个整数,分别表示罗宾的兄弟和母亲的最佳开始日期。两次拜访都必须在第1天和第n天之间(包括第1天和第n天)。

解题思路:

        用差分,来记录区间的变化,要注意的是因为有一段工作在,就需要记录,而不是要包含这个工作,所以分别用a,b来记录工作的开始结束。先算出前d天,然后之后每次减去i-d天结束的加上i天开始的。

代码如下:
#include <bits/stdc++.h>
using namespace std;
#define int long long

int n;
signed main()
{
    int t;
    cin >> t;
    int d, k;
    while (t--)
    {
        cin >> n >> d >> k;
        int l, r;
        vector<int> a(100005, 0);
        vector<int> b(100005, 0);
        for (int i = 1; i <= k; i++)
        {
            cin >> l >> r;
            a[l]++;
            b[r]--;
        }
        int x, y;
        int max1 = 0, min1 = n;
        int s = 0;
        for (int i = 1; i <= d; i++)
        {
            if (a[i] == 1)
            {
                s++;
            }
        }
        x = 1, y = 1;
        max1 = s;
        min1 = s;
        for (int i = d + 1; i <= n; i++)
        {
            if (b[i - d] < 0)
            {
                s += b[i - d];
            }
            s += a[i];
            if (max1 < s)
            {
                max1 = s;
                x = i - d + 1;
            }
            if (min1 > s)
            {
                min1 = s;
                y = i - d + 1;
            }
        }
        cout << x << " " << y << endl;
    }
}

### 回答1: robin_hood::unordered_set是一种基于开放寻址的哈希表实现,它是C++ STL中的一个无序集合容器。与标准的unordered_set相比,robin_hood::unordered_set有着更高的性能。 robin_hood::unordered_set的实现方式采用了"robin hood"哈希算法,这种算法通过再哈希的方式处理冲突,将冲突的元素移到更远的位置,从而保持高效的查找性能。这种算法使得插入和删除操作具有O(1)的时间复杂度,而查找操作虽然在最坏情况下也是O(n),但实际上在大多数情况下是O(1)的。 此外,robin_hood::unordered_set在内存使用上也比标准的unordered_set更为高效。它采用了连续的内存布局,并使用了布隆过滤器来减少哈希冲突的数量,从而减少了内存的占用。 使用robin_hood::unordered_set时,可以通过插入、删除和查找等操作来管理集合中的元素。插入操作可以将元素添加到集合中,删除操作可以从集合中移除指定的元素,而查找操作可以判断集合中是否存在某个元素。 总的来说,robin_hood::unordered_set是一种高效的无序集合容器,适用于需要频繁进行插入、删除和查找操作的场景。它通过"robin hood"哈希算法和优化的内存使用方式,在性能和内存占用方面均有优势。 ### 回答2: Robin Hood是一个著名的英雄人物,他以偷取富人财物来帮助穷人而闻名。而unordered_set是C++ STL库中的一个数据结构,它是一个无序的集合,允许快速地插入、查找和删除元素。 尽管二者似乎没有直接联系,但是我们可以通过一些类比来理解它们之间的关系。就像Robin Hood通过偷取富人的财物来帮助穷人一样,unordered_set可以用来解决一些问题,比如查找和删除元素,这些问题在其他数据结构中可能需要更多的时间和资源。 就像Robin Hood能够迅速地从富人身上夺取财物,unordered_set在最佳情况下能够以O(1)的时间复杂度插入、查找和删除元素,这取决于哈希函数的性能。这使得它在一些需要高效率操作的场景中非常有用,比如去重、查找等。 然而,就像Robin Hood有时候可能会遇到困难一样,unordered_set也有一些限制。由于其无序的特点,它在有序访问元素方面相对较弱。此外,当元素数量较大时,哈希冲突的概率也会增加,导致性能下降。因此,在某些情况下,我们可能需要考虑使用其他更适合的数据结构。 总之,尽管Robin Hood和unordered_set在本质上是不同的,但通过类比,我们可以更好地理解unordered_set的特点和用途。无论是Robin Hood还是unordered_set,它们都有自己独特的功能和限制,我们需要根据具体的问题和需求来选择使用它们。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值