Codeforces Round #737 (Div. 2) 题解(A-C)
Posted 陌默z
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #737 (Div. 2) 题解(A-C)相关的知识,希望对你有一定的参考价值。
Codeforces Round #737 (Div. 2) 题解(A-C)
A. Ezzat and Two Subsequences
题目大意:
给定 n n n个整数,将这 n n n个整数分成两组,使得两组整数的平均数之和最大,输出这个最大的平均数之和。
解题思路:
通过观察样例可以发现,只要将最大的整数单独作为一组就行了。
那么为什么这样是对的呢,可以考虑进行这样分组之和,从 n − 1 n-1 n−1个整数那组拿任意一个整数过来能否取得更优的解,列个式子推一推就能明白了,因为本人比较懒就不写详细的证明过程了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+10;
int a[N];
int n;
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+1+n);
double sum=0;
for(int i=1;i<n;i++) sum+=a[i];
sum/=(n-1);
printf("%.8f\\n",sum+a[n]);
}
return 0;
}
B. Moamen and k-subarrays
题目大意:
给出 n n n个不同的整数,问是否能将这 n n n个整数分成 k k k块连续的子数组之后,通过移位组合成一个升序的数组。
解题思路:
因为分块过后,子数组内部的顺序是不会发生改变的,而我们最后要得到的数组一定是按照严格的顺序排好的。
所以只要我们将整个数组按照升序排序,得到每个数组在升序数组中的位置。
设 a i a_i ai在最终数组的下标是 b i b_i bi,那么当且仅当 b i = b i − 1 + 1 b_i=b_{i-1}+1 bi=bi−1+1的情况下 a i 和 a i − 1 a_i和a_{i-1} ai和ai−1才能分到同一块中。
相对的,如果 b i ≠ b i − 1 + 1 b_i\\neq b_{i-1}+1 bi=bi−1+1,那么 b i b_i bi和 b i − 1 b_{i-1} bi−1一定要被分成两块。
要注意的一点是分成一块是没有意义的,所以我们要将答案初始化为 1 1 1。
时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int a[N],b[N];
int n,k;
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&k);
vector<int> v;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
v.push_back(a[i]);
}
sort(v.begin(),v.end());
for(int i=0;i<n;i++) b[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin();
int res=1;
for(int i=1;i<n;i++){
if(b[i]!=b[i-1]+1) res++;
}
puts(k>=res?"YES":"NO");
}
return 0;
}
C. Moamen and XOR
题目大意:
构造一个 n n n个整数的数组 a a a,其中每个整数都要小于 2 k 2^k 2k。
问有多少种方案能够使得以下条件成立:
a 1 & a 2 & a 3 & . . . & a n ≥ a 1 ⊕ a 2 ⊕ a 3 ⊕ . . . ⊕ a n a_1\\And a_2 \\And a_3\\And...\\And a_n\\ge a_1\\oplus a_2 \\oplus a_3\\oplus ...\\oplus a_n a1&a2&a3&...&an≥a1⊕a2⊕a3⊕...⊕an
解题思路:
做法有点像数位dp,但其实也可以说是二进制的线性dp。
因为所有整数要小于 2 k 2^k 2k,所以对于每个整数在二进制的表示下最多只有 k k k位(如果 k = 0 k=0 k=0的话,那所有数都等于1,答案也就是1)。
所以我们从高位向低位考虑,考虑每一位的所有情况:
- 如果当前位 & \\And &和 ⊕ \\oplus ⊕的结果分别是 1 1 1和 1 1 1,那么只有所有数这一位都为 1 1 1,并且n是奇数,一共只有 1 1 1种情况。
- 如果当前位 & \\And &和 ⊕ \\oplus ⊕的结果分别是 1 1 1和 0 0 0,那么只有所有数这一位都为1,并且n是偶数,一共只有 1 1 1种情况。
- 如果当前位
&
\\And
&和
⊕
\\oplus
⊕的结果分别是
0
0
0和
1
1
1,那么只有奇数个数的这一位为1,并且不能全部的数这一位都为1。
方案数: { 2 n − 1 − 1 n % 2 = 1 2 n − 1 n % 2 = 0 \\begin{cases}2^{n-1}-1&n\\%2=1 \\\\ 2^{n-1} \\ &n\\%2=0\\end{cases} {2n−1−12n−1 n%2=1n%2=0 - 如果当前位
&
\\And
&和
⊕
\\oplus
⊕的结果分别是
0
0
0和
0
0
0,那么只有偶数个数的这一位为1,并且不能全部的数这一位都为1。
方案数: { 2 n − 1 n % 2 = 1 2 n − 1 − 1 n % 2 = 0 \\begin{cases}2^{n-1}&n\\%2=1 \\\\ 2^{n-1}-1 \\ &n\\%2=0\\end{cases} {2n−12n−1−1 n%2=1n%2=0
可能会有人不知道 2 n − 1 2^{n-1} 2n−1怎么来的,众所周知组合数的和 ∑ n = 0 m C m n = 2 m \\sum\\limits_{n=0}^m C_m^n=2^m n=0∑mCmn=2m,其中奇数项和偶数项的和都等于 2 m − 1 2^{m-1} 2m−1。
设 f [ i ] [ 0 ] f[i][0] 以上是关于Codeforces Round #737 (Div. 2) 题解(A-C)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #737 (Div. 2) 题解
Codeforces Round #737 (Div. 2) 题解
Codeforces Round #737 (Div. 2) 题解
Codeforces Round #737 (Div. 2) Ezzat and Grid(线段树优化dp)