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 n1个整数那组拿任意一个整数过来能否取得更优的解,列个式子推一推就能明白了,因为本人比较懒就不写详细的证明过程了。

代码:

#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=bi1+1的情况下 a i 和 a i − 1 a_i和a_{i-1} aiai1才能分到同一块中。

相对的,如果 b i ≠ b i − 1 + 1 b_i\\neq b_{i-1}+1 bi=bi1+1,那么 b i b_i bi b i − 1 b_{i-1} bi1一定要被分成两块。

要注意的一点是分成一块是没有意义的,所以我们要将答案初始化为 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&...&ana1a2a3...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} {2n112n1 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} {2n12n11 n%2=1n%2=0

可能会有人不知道 2 n − 1 2^{n-1} 2n1怎么来的,众所周知组合数的和 ∑ n = 0 m C m n = 2 m \\sum\\limits_{n=0}^m C_m^n=2^m n=0mCmn=2m,其中奇数项和偶数项的和都等于 2 m − 1 2^{m-1} 2m1

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)

Codeforces Round #737 (Div. 2)(补题)

Codeforces Round #737 (Div. 2) C