Codeforces Round #717 (div.2)

A

题意

有一个长度为\(n(2\leq n\leq 100)\)的数组,最多进行\(k(1\leq k\leq 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\n",a[n]);
    }
}

B

题意

有一个长度为\(n(2\leq n\leq 2000)\)的数组\(a\)\(0\leq 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\n",f?"YES":"NO");
    }
}

C

题意

给出一个长度为\(n(2\leq n\leq 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\n");
    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\n%d\n",id);
    }
}

D

E

posted @ 2021-04-22 23:42  fxq1304  阅读(36)  评论(0编辑  收藏  举报