CF VP Day2 Codeforces Round #717 (Div. 2) A B C
A. Tit for Tat
思路: 水题
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int a[N];
void solve(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
while(a[i]>0&&k>0){
a[i]-=1;
a[n]+=1;
k--;
}
}
for(int i=1;i<=n;i++)cout<<a[i]<<' ';
cout<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
B. AGAGA XOOORRR
思路: 稍难, b 2 b2 b2到了 1500 1500 1500的分,一个性质很容易知道,所有数的 x o r xor xor为 0 0 0一定 o k ok ok,因为可以被构造成两个数,这两个数不管是啥, x o r xor xor一定是 0 0 0,因为相等,该为偶数个情况。奇数个情况不管是多少个相等,若满足条件,一定可以构造成 3 3 3个相等的部分,因为剩余多的块都可以像偶数块一样直接 x o r = 0 xor=0 xor=0掉。又因为相邻的数才能进行 x o r xor xor,所以直接 O ( n ) O(n) O(n)扫描即可。
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2010;
int a[N];
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int res=0;
for(int i=1;i<=n;i++)cin>>a[i],res^=a[i];
if(res==0){
cout<<"YES"<<endl;
continue;
}
else{
int ans=0;
int sum=0;
for(int i=1;i<=n;i++){
ans^=a[i];
if(ans==res){
sum++;
ans=0;
}
}
if(sum>=3)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
return 0;
}
C. Baby Ehab Partitions Again
思路: 分类讨论题: 如果所有数的和为奇数,那么必定是 g o o d good good数组,否则如果和为偶数,并且数组中出现奇数。那么也有可能分解成两个和相等的数组,因为有可能出现不止一个奇数,那么此时我们需要通过一次操作将奇数去除。否则如果数组中没有奇数并且和是偶数的情况下,我们可以将等式中所有数除以 2 2 2,和原式是等价的,直至出现奇数。那么如何判断存在奇数元素且总和为偶数的数组能够分解为两个和相等的数组呢?此时用到01背包当然也可以直接使用 b i t s e t bitset bitset进行求数,统计所有情况,检验是否出现 和 / 2 和/2 和/2的情况,是的话需要操作,否则无需操作。
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int a[N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
while(1){
bool ok = true;
for(int i=1;i<=n;i++){
if(a[i]%2)ok = false;
}
if(!ok)break;
for(int i=1;i<=n;i++)a[i]/=2;
}
int ans=0;
for(int i=1;i<=n;i++)ans+=a[i];
if(ans%2){
cout<<0<<endl;
return 0;
}
bitset<200010>dp;
dp[0]=1;
for(int i=1;i<=n;i++){
dp|=dp<<(a[i]);
}
if(!dp[ans/2]){
cout<<0<<endl;
}
else{
int id;
for(int i=1;i<=n;i++){
if(a[i]%2){
id=i;
break;
}
}
cout<<1<<endl;
cout<<id<<endl;
}
return 0;
}