题意:
给你n个数a[i]和k、p,表示将这些数一共分成k组,组内数和为偶数的有p组(其他的为奇数),问你是否可以分。
思路:
这里我们只关心数的奇偶不关心大小,所以我们把所有奇数和偶数分开存。然后考虑下列公式:
偶数+偶数=偶数
奇数+奇数=偶数
奇数+偶数=奇数
可知,奇数个数不能创造的,所以我们可以先判断奇数个数num1是否大于k-p。然后先放奇数组,每组放1个奇数其他拿去凑偶数,偶数放时就要循环放了(刚开始我的思路是前p-1组都放1个偶数,最后一组把其他的所有数都塞进去,但是这样wrong了,估计后台判断的时候最后一组加爆了int32无法判断奇偶)。注意要考虑下p为0的情况,p为0时我们之前的奇数组也得循环放了。
#include<cstdio>
#include<vector>
using namespace std;
const int MAX=1e5+5;
int n,k,p,a[MAX];
int num1,num2;
vector<int> v1,v2,ans[MAX];
bool ok(){
if(k-p>num1) return false;
int t1=0,t2=0;
for(int i=0;i<k-p;i++){
ans[i].push_back(v1[t1++]);
}
if((num1-t1)%2) return false;
if(p>num2+(num1-t1)/2) return false;
if(p){
int i=k-p;
while(t1<num1){
ans[i].push_back(v1[t1++]);
ans[i].push_back(v1[t1++]);
i++;
if(i==k) i=k-p;
}
while(t2<num2){
ans[i].push_back(v2[t2++]);
i++;
if(i==k) i=k-p;
}
}
else{
int i=0;
while(t1<num1){
ans[i].push_back(v1[t1++]);
ans[i].push_back(v1[t1++]);
i++;
i%=k;
}
while(t2<num2){
ans[i].push_back(v2[t2++]);
i++;
i%=k;
}
}
return true;
}
int main(){
scanf("%d%d%d",&n,&k,&p);
num1=num2=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]%2) num1++,v1.push_back(a[i]);
else num2++,v2.push_back(a[i]);
}
if(ok()){
printf("YES\n");
for(int i=0;i<k;i++){
printf("%d",ans[i].size());
for(int j=0;j<ans[i].size();j++){
printf(" %d",ans[i][j]);
}
printf("\n");
}
}
else printf("NO\n");
return 0;
}