zoukankan      html  css  js  c++  java
  • Codeforces Round #717 (div.2)

    A

    题意

    有一个长度为(n(2leq nleq 100))的数组,最多进行(k(1leq kleq 10000))次操作,每次可以选择两个不同的元素,一个加(1),一个减(1),数组中的元素必须始终是非负数,计算可以得到的字典序最小的数组

    题解

    由于要求字典序最小,所以每次下标最小的非零元素减少,最后一个元素增加

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
     
    const int maxn=110;
    int T,n,k,a[maxn];
    
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d %d",&n,&k);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            for(int i=1;i<n;i++){
                if(k>=a[i]){
                    a[n]+=a[i];
                    k-=a[i];
                    a[i]=0;
                }
                else{
                    a[n]+=k;
                    a[i]-=k;
                    k=0;
                }
            }
            for(int i=1;i<n;i++) printf("%d ",a[i]);
            printf("%d
    ",a[n]);
        }
    }
    

    B

    题意

    有一个长度为(n(2leq nleq 2000))的数组(a)(0leq a_i<2^{30}),每次操作可以将相邻两个数替换成它们的异或值,判断能否经过若干次操作,使得数组中元素个数大于等于(2)并且所有元素都相等

    题解

    由于每次操作合并的是相邻两个数,所以最终数组相当于由原数组划分成若干段,段内元素异或构成。段数为(2)或者为(3),因为如果超过(3),则可以选择连续的(3)个元素合并。所以等价于判断将数组划分成(2)段或者(3)段,段内异或的值是否相等。建立前缀异或数组(pre),分成(2)段的情况可以直接判断(pre[n])是否为(0),分成(3)段的情况可以枚举分界点判断,时间复杂度(O(n^2))

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    
    const int maxn=2010;
    int T,n,a[maxn],pre[maxn];
    
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            pre[0]=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                pre[i]=pre[i-1]^a[i];
            }
            bool f=!pre[n];
            for(int i=1;i<=n;i++){
                for(int j=i+1;j<=n;j++){
                    f|=(pre[i]==(pre[j]^pre[i])) && (pre[i]==(pre[n]^pre[j]));
                }
            }
            printf("%s
    ",f?"YES":"NO");
        }
    }
    

    C

    题意

    给出一个长度为(n(2leq nleq 100))的序列,定义一个序列是好的当且仅当他无法被分成两个和相同的子序列。判断最少删去几个元素可以使得这个序列变成好的,并且输出删去的元素下标

    题解

    如果序列中元素和为奇数,则它无法被分成两个和相同的子序列,所以它一定是好的。
    如果序列中元素和为偶数,可以通过背包(dp)判断是否存在一个子序列的和为原序列和的一半,如果不存在,则原序列也是好的。如果存在,则如果序列中有奇数,删掉这个数,序列和变成奇数,成为好序列。如果序列中不存在奇数,则将序列中元素全部除以(2),则成为了和原先一样的问题,这样不断操作,直到找到一个奇数即可。所以相当于找到序列中(lowbit(x))最小的元素

    #include<bits/stdc++.h>
    #define LL long long
    #define lowbit(x) x&(-x)
    using namespace std;
    
    const int maxn=110,maxm=200010;
    int n,a[maxn];
    bitset<maxm> b;
    
    bool bad(){
        int sum=0;
        for(int i=1;i<=n;i++){
            sum+=a[i];
        }
        if(sum&1) return false;
        b[0]=1;
        for(int i=1;i<=n;i++){
            b|=(b<<a[i]);
        }
        return b[sum/2];
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        if(!bad()) printf("0
    ");
        else{
            int id,mini=2010;
            for(int i=1;i<=n;i++){
                int t=lowbit(a[i]);
                if(mini>t){
                    mini=t;
                    id=i;
                }
            }
            printf("1
    %d
    ",id);
        }
    }
    

    D

    E

  • 相关阅读:
    JSON格式解析和libjson使用简介(关于cjson的使用示例)
    我还没死!!微信公众号——自媒体的营销之路
    android应用开发-从设计到实现 3-4 静态原型的状态栏
    一种绝对提高开发水平的方法
    年近30------职业回想与思考
    LeetCode Populating Next Right Pointers in Each Node
    uploadify在火狐下上传不了的解决方式,java版(Spring+SpringMVC+MyBatis)具体解决方式
    struct和typedef struct
    奔五的人学ios:swift竟然没有字符串包括,找个简单的解决方法
    Floyd算法解说
  • 原文地址:https://www.cnblogs.com/fxq1304/p/14692023.html
Copyright © 2011-2022 走看看