首页 > 其他分享 >题解:Codeforces Round 961 (Div. 2) B1&B2

题解:Codeforces Round 961 (Div. 2) B1&B2

时间:2024-07-25 16:52:18浏览次数:11  
标签:std 10 le 961 int 题解 Codeforces 花瓣 test

本题含有B1和B2两个难度版本。由于关系相近,我把他们放在同一篇博客中,可自行选择观看

B1. Bouquet (Easy Version)

time limit per test: 1.5 seconds

memory limit per test: 512 megabytes

input: standard input

output: standard output

This is the easy version of the problem. The only difference is that in this version, the flowers are specified by enumeration.

A girl is preparing for her birthday and wants to buy the most beautiful bouquet. There are a total of \(n\) flowers in the store, each of which is characterized by the number of petals, and a flower with \(k\) petals costs \(k\) coins. The girl has decided that the difference in the number of petals between any two flowers she will use in her bouquet should not exceed one. At the same time, the girl wants to assemble a bouquet with the maximum possible number of petals. Unfortunately, she only has \(m\) coins, and she cannot spend more. What is the maximum total number of petals she can assemble in the bouquet?

这是问题的简单版本。唯一不同的是,在这个版本中,花朵是通过枚举来指定的

一个女孩准备过生日,她想买一束最漂亮的花。商店里一共有 \(n\) 种花,每种花的特征是花瓣数,有 \(k\) 个花瓣的花需要花费 \(k\) 个硬币。女孩决定,花束中任何两朵花的花瓣数之差都不能超过 1。同时,女孩希望花束的花瓣数尽可能多。不幸的是,她只有 \(m\) 枚金币,无法再花费更多。她能组合的花束的花瓣总数最多是多少?

Input

Each test consists of several test cases. The first line contains a single integer \(t\) (\(1 \le t \le 10\,000\)) — the number of test cases. This is followed by descriptions of the test cases.

The first line of each test case contains two integers \(n\), \(m\) (\(1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18}\)) — the number of flowers in the store and the number of coins the girl possesses, respectively. The second line of each test case contains \(n\) integers \(a_1, a_2, \ldots, a_n\) (\(1 \le a_i \le 10^9\)), where \(a_i\) is the number of petals of the \(i\)-th flower in the store.

The sum of \(n\) over all test cases does not exceed \(2 \cdot {10}^5\).

输入

每个测试由多个测试用例组成。第一行包含一个整数 \(t\) ( \(1 \le t \le 10\,000\) ) - 测试用例数。随后是测试用例的说明。

每个测试用例的第一行包含两个整数 \(n\) , \(m\) ( \(1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18}\) )--分别是商店里的鲜花数量和女孩拥有的硬币数量。每个测试用例的第二行包含 \(n\) 个整数 \(a_1, a_2, \ldots, a_n\) ( \(1 \le a_i \le 10^9\) ),其中 \(a_i\) 是商店里第 \(i\) 朵花的花瓣数。

所有测试用例的 \(n\) 之和不超过 \(2 \cdot {10}^5\) 。

Output

For each test case, output a single integer — the maximum possible number of petals in the bouquet that the girl can assemble while meeting all the conditions listed above.

输出

对于每个测试用例,输出一个整数,即在满足上述所有条件的情况下,女孩在花束中可能组合的最大花瓣数。

Example
input

5
5 10
1 1 2 2 3
8 20
4 2 7 5 6 1 1 1
8 100000
239 30 610 122 24 40 8 2
11 13
2 4 11 1 1 2 3 5 4 3 2
8 1033
206 206 206 207 207 207 207 1000

output

7
13
610
13
1033

Note

In the first test case, you can assemble a bouquet with \((1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2)\). The maximum over all valid bouquets not greater than \(10\) is \(7\) for \((2, 2, 3)\). In the third test case, you can assemble a bouquet with only one flower of any type, so the answer is \(610\). In the fourth test case, you can assemble a bouquet with \((4, 4, 5)\), which gives you \(13\) petals, and it is the maximum amount of petals that the girl can buy.

在第一个测试用例中,可以用 \((1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2)\) 组合一个花束。所有不大于 \(10\) 的有效花束的最大值是 \(7\) ,即 \((2, 2, 3)\) 。在第三个测试案例中,你只能用一朵任意类型的花来组合花束,因此答案是 \(610\) 。在第四个测试案例中,你可以用 \((4, 4, 5)\) 组合一束花,这样就可以得到 \(13\) 个花瓣,这也是女孩可以购买的最大花瓣数量。

我的题解
第一题是简单版本,给的数据量比较小
我们可以先排一下序,然后用 双指针算法 模拟 取值

后面的指针指向的值前面的值加1 要大,就把前面的指针不断往后挪
每次更新区间和

每次对区间和做一个判断

  • 当区间和大于 \(k\) 时,就把前指针往后挪(减少区间和)
  • 否则,就把后指针往后挪(增大区间和)

每次循环都把区间和与答案作比较,取最大值更新答案
循环结束之后输出答案即可

我的代码

#include <bits/stdc++.h>
#define int long long

const int N = 2e5+10;
int t,n,k;
int num;
int a[N];

void solve() {
    int ans =  0;
    int tem;
    std::cin >> n >> k;
    for(int i = 0 ; i < n ; i ++) std::cin >> a[i];
    std::sort(a,a+n);
    int st = 0,en = 0;
    tem = a[0];
    while(st <= en && en < n) {
        while(a[st] +1 < a[en]) {
            tem -= a[st];
            st ++;
        }

        if(tem > k) {
            tem -= a[st];
            st ++;
        } else {
            ans = std::max(ans,tem);
            en ++;
            tem += (en < n ? a[en] : 0);
        }
    }

    std::cout << ans << "\n";
}

signed main() {
    std::cin >> t;
    while(t--) solve();
    return 0;
}

B2. Bouquet (Hard Version)

time limit per test: 1.5 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

This is the hard version of the problem. The only difference is that in this version, instead of listing the number of petals for each flower, the number of petals and the quantity of flowers in the store is set for all types of flowers.

A girl is preparing for her birthday and wants to buy the most beautiful bouquet. There are a total of \(n\) different types of flowers in the store, each of which is characterized by the number of petals and the quantity of this type of flower. A flower with \(k\) petals costs \(k\) coins. The girl has decided that the difference in the number of petals between any two flowers she will use to decorate her cake should not exceed one. At the same time, the girl wants to assemble a bouquet with the maximum possible number of petals. Unfortunately, she only has \(m\) coins, and she cannot spend more. What is the maximum total number of petals she can assemble in the bouquet?

**这是问题的困难版本。唯一不同的是,在这个版本中,不是列出每种花的花瓣数,而是为所有类型的花设定花瓣数和商店中的花的数量。

一个女孩准备过生日,想买一束最漂亮的花。店里一共有 \(n\) 种不同类型的花,每种花的花瓣数和数量都有相应的特征。一朵有 \(k\) 个花瓣的花的价格是 \(k\) 个金币。女孩决定,她用来装饰蛋糕的任何两朵花的花瓣数之差都不能超过 1。同时,女孩还想用尽可能多的花瓣组合成一束花。不幸的是,她只有 \(m\) 枚金币,无法再花费更多。她能组合的花束花瓣总数最多是多少?

Input

Each test consists of several test cases. The first line contains a single integer \(t\) (\(1 \le t \le 10\,000\)) — the number of test cases. This is followed by descriptions of the test cases.

The first line of each test case contains two integers \(n\), \(m\) (\(1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18}\)) — the number of types of flowers in the store and the number of coins the girl possesses, respectively. The second line of each test case contains \(n\) different integers \(a_1, a_2, \ldots, a_n\) (\(1 \le a_i \le 10^9\)), where \(a_i\) is the number of petals of the \(i\)-th flower type in the store (for different indexes \(i \neq j\), it must be \(a_i \neq a_j\)). The third line of each test case contains \(n\) integers \(c_1, c_2, \ldots, c_n\) (\(1 \le c_i \le 10^9\)), where \(c_i\) is the quantity of the \(i\)-th flower type in the store.

The sum of \(n\) over all test cases does not exceed \(2 \cdot {10}^5\).

输入

每个测试由多个测试用例组成。第一行包含一个整数 \(t\) ( \(1 \le t \le 10\,000\) ) - 测试用例数。随后是测试用例的说明。

每个测试用例的第一行包含两个整数 \(n\) , \(m\) ( \(1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18}\) ) - 分别是商店中鲜花的种类数和女孩拥有的硬币数。每个测试用例的第二行包含 \(n\) 不同的整数 \(a_1, a_2, \ldots, a_n\) ( \(1 \le a_i \le 10^9\) )。( \(1 \le a_i \le 10^9\) ),其中 \(a_i\) 是商店中 \(i\) /th花朵类型的花瓣数(对于不同的索引 \(i \neq j\) ,必须是 \(a_i \neq a_j\) )。每个测试用例的第三行包含 \(n\) 个整数 \(c_1, c_2, \ldots, c_n\) ( \(1 \le c_i \le 10^9\) ),其中 \(c_i\) 是商店中 \(i\) -th 鲜花类型的数量。

所有测试用例中 \(n\) 的总和不超过 \(2 \cdot {10}^5\) 。

Output

For each test case, print one integer — the maximum possible number of petals in a bouquet that a girl can collect, observing all the conditions listed above.

输出

对于每个测试用例,打印一个整数 - 在遵守上述所有条件的情况下,女孩在花束中可能收集到的最大花瓣数。

Example
input

7
3 10
1 2 3
2 2 1
3 1033
206 207 1000
3 4 1
6 20
4 2 7 5 6 1
1 2 1 3 1 7
8 100000
239 30 610 122 24 40 8 2
12 13123 112 1456 124 100 123 10982
6 13
2 4 11 1 3 5
2 2 1 2 2 1
8 10330
206 210 200 201 198 199 222 1000
9 10 11 12 13 14 15 16
2 10000000000
11 12
87312315 753297050

output

7
1033
19
99990
13
10000
9999999999

Note

In the first test case, some valid bouquets are \((1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2)\). The maximum over all valid bouquets not greater than \(10\) is \(7\) for \((2, 2, 3)\). In the second test case, you can assemble a valid bouquet with \((206, 206, 207, 207, 207)\) with a sum of \(1033\), which is the maximum number of petals the girl can buy. In the third test case, you can assemble a valid bouquet with \((5, 5, 5, 4)\) with a sum of \(19\). It can be seen that no valid bouquet can have \(20\) petals.

在第一个测试用例中,一些有效花束为 \((1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2)\) 。不大于 \(10\) 的所有有效花束的最大值是 \((2, 2, 3)\) 的 \(7\) 。在第二个测试案例中,可以用 \((206, 206, 207, 207, 207)\) 组合出一个有效花束,花束总数为 \(1033\) ,这是女孩可以购买的最大花瓣数。在第三个测试用例中,可以用 \((5, 5, 5, 4)\) 和 \(19\) 组合出一束有效的花束。由此可见,任何有效花束都不可能有 \(20\) 个花瓣。

我的题解
这题是困难版本
我们可以用计数数组来模拟这个双指针算法的过程以节省内存空间
当然也可以用pair存储,我用的是map存储

我的做法是计数存储之后,
声明一个关于这个map的迭代器,反向遍历
假设迭代器迭代到取花瓣数 \(a\)
每次遍历都只取 \(a\) 和 \(a+1\) 的花瓣数

每次计算,假设迭代器迭代到取花瓣数 \(a\) 和花瓣数 \(b(b = a + 1)\):
先比较 \(a\) 和 \(b\) 总数和 \(k\) 的大小

  • 如果小于等于 \(k\),那就全部取
  • 如果比 \(k\) 大
    1. 假设全部取 \(a\) ,会有两种情况
      • 全部取 \(a\) 之后手上的花瓣数不超过 \(k\) ,那就再从 \(b\) 那里拿一些花瓣(假设取 \(m\) 朵,使得手上的花瓣数最大且不超过 \(k\) )
      • 全部取 \(a\) 之后手上的花瓣数超过 \(k\) ,那就放回部分 \(a\) ,使得手上的花瓣数不大于 \(k\)
    2. 然后,我们计算最多能把多少朵手上的a换成b(因为每换一朵花瓣数就加 \(1\)),这个数量 $$add = min(剩下的b,手中的a)$$
      也就是 $$add = min(b的总数 - m,手中的a)$$
    3. 再把手上的花瓣数加上 \(add\),和目前的结果比较,取最大值更新结果

输出最后的结果即可
同样的逻辑套用在B1也可以通过

我的代码

#include <bits/stdc++.h>
#define int long long

const int N = 2e5+10;
int t,n,k;
int num;
int a[N];

int fin(std::map<int,int> &mp,std::map<int,int>::iterator &poi) {
    int bi = poi->first+1;
    int teme = poi->second * poi->first + mp[bi] * bi;
    int ans_t;

    if(teme > k) {
        ans_t = std::min(k/poi->first,poi->second) * poi->first;
        int add_m = std::min((k-ans_t)/bi,mp[bi]);
        ans_t += add_m*bi;

        int add_t = std::min(std::min(k/poi->first,poi->second),mp[bi]-add_m);
        ans_t += std::min(k-ans_t,add_t);
        ans_t = std::max(ans_t,std::min(k/bi , mp[bi]) * bi);
        return ans_t;
    } else {
        return teme;
    }
}

void solve() {
    int ans =  0;

    std::cin >> n >> k;
    std::map<int,int> mp;
    for(int i = 0 ; i < n ; i ++) {
        std::cin >> a[i];
    }
    for(int i = 0 ; i < n ;i ++) {
        std::cin >> mp[a[i]];
    }

    std::map<int,int>::iterator poi = mp.end();
    poi --;

    while(poi != mp.begin() && ans < k) {
        ans = std::max(ans,fin(mp,poi));
        poi --;
    }

    ans = std::max(ans,fin(mp,poi));

    std::cout << ans << "\n";
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    std::cin >> t;
    while(t--) solve();
    return 0;
}

标签:std,10,le,961,int,题解,Codeforces,花瓣,test
From: https://www.cnblogs.com/jiejiejiang2004/p/18322498

相关文章

  • CF568C New Language 题解
    Description将\(\texttt{a}\sim\texttt{a}+l-1\)这\(l\)个字符分成\(\texttt{V,C}\)两个集合。你需要构造一个长度为\(n\)且满足\(m\)个限制且不小于另一个长度为\(n\)的字符串\(s\)的最小字符串。每一个限制为若字符串的第\(p_1\)个位置上的字符\(\in......
  • CF22E 题解
    题面注意到题目给的图为基环树森林。因为一个(\(n>1\))的强连通图每个点都要有出度和入度,所以:对于每个基环树,叶子结点是没有入度的,所以一定要有一条从环上出发的路径经过这个点。对于基环树的环,注意到它缩点后没有出度,所以一定要有一条出边。注意到叶子结点的需求和根节点相反,......
  • 题解:AT_arc116_e [ARC116E] Spread of Information
    题目链接思路看到最大值最小首先可以想到二分,发现答案具有单调性,那么思考如何在\(O(n)\)的时间内判断是否合法。考虑贪心,在最远没覆盖的点的距离和要判断的\(mid\)刚好相等的时侯再选择一定不劣,因为这样覆盖的点最多,那么从叶子节点向上回溯,处理它的所有儿子,判断是否选择该......
  • LG3107 [USACO14OPEN] Odometer S 题解 (数位DP+容斥)
    题意定义一个数是神奇的当且仅当这个数中有一个数位出现了一半及以上,比如112,2233。求\([l,r]\)中有多少个好的数字,\(100\lel,r\le10^{18}\)。题解考虑数位DP,先把答案转为\(Ans(r)-Ans(l-1)\),我们钦定一个数\(k\)让他必须出现多于一半,然后我们想求\([1,x]\)中有多少......
  • CF1015F 题解
    题面考虑这样的匹配问题,可以想如何确定第一次匹配,这样可以不重不漏地计数。考虑dp的时候同时维护有几个括号没有匹配,匹配到\(s\)的第几位,所以令\(f(i,j,k)\)表示dp到(要计数的序列的)第\(i\)个字符,有\(j\)个左括号没有匹配,匹配到\(s\)的第\(k\)位。转移很容易,考......
  • 程序设计:C++入门教程(速成) + 15道经典例题(附带例题解析)
    本文章以实用为主,若实在是不明白文字所表达的内容,无脑复制代码,自己动手运行一下,实验一下即可理解文章内容,放心,代码是全的,全选复制粘贴即可不废话,直接开整数据类型常用数据类型int:整数类型,用于表示整数值。例如:1,2,-3,0等。float:单精度浮点数类型,用于表示带有小数点的数......
  • AT_arc116_e [ARC116E] Spread of Information 题解
    题目传送门前置知识二分答案|树形DP解法答案显然具有单调性,考虑二分答案。设当前二分出的答案为\(mid\),则等价于覆盖距离为\(mid\)的情况下进行选点。做法同luoguP3942将军令,考虑进行贪心,对于深度最深的叶节点将选择的点放在边界时,即取\(mid\)级祖先时,覆盖的范......
  • 题解—[ABC265E] Warp
    题面简单计数DP。由于数据范围很大,所以状态不能常规设置为\(dp_{i,j}\)。注意到\(n\)只有\(300\),考虑设\(dp_{i,j,k}\)表示三种行走方法分别使用\(i\),\(j\),\(k\)次的路径数量。状态转移很简单,先计算出来当前所在位置,如果是障碍就跳过,否则$dp_{i,j,k}=dp_{i-1,j,k}+dp......
  • P2671 [NOIP2015 普及组] 求和 题解
    题目:P2671NOIP2015普及组求和题意给定一个带有颜色和数字的序列,我们要寻找三元组\((x,y,z)\)满足以下条件:\(y\)为\(x\)和\(z\)的中点且都为整数。\(color[x]=color[z]\)。我们命这样一个三元组对答案的贡献为\((x+z)*(num[x]+num[z])\)。整个序列的总价值为每个......
  • Temperature 题解
    前言题目链接:洛谷;SPOJ;Hydro&bzoj。题意简述有一个长度为\(n\)的序列,每个位置值的范围为\([L_i,R_i]\)内,求原序列可能的最长不降子串长度。题目分析尝试找一些性质。发现,连续一段合法的区间,都能分成若干真正参与最长不降子串,以及紧跟着的若干包含\(L_i\)的位置。下图......