Codeforces 439C Devu and Partitioning of the Array

来源:互联网 发布:网络推广的技巧 编辑:程序博客网 时间:2024/05/21 21:44

题意:

给你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;}



0 0
原创粉丝点击