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);
}
}