http://codeforces.com/problemset/problem/439/C
题意:给你n个数,分成k个非空集合,其中有p个集合的元素和为偶数,其余k-p个集合的元素和为奇数。
思路:考虑两个数和的情况,奇+奇=偶,奇+偶=奇,偶+偶=偶。所以解决方案不存在的情况为
(oddnum<k-p || (oddnum-(k-p))%2!=0 || evennum+(oddnum-(k-p))/2<p)。
先输出k-p-1组的单个奇数,输出p-1组偶数(先为单个偶数,偶数不够两个奇数),若(k!=0&&k-p!=0),输出一个奇数,其余数一组输出。
#include<cstdio> #include<iostream> using namespace std; int even[100020],odd[100020]; int main() { int n,k,p,evennum=0,oddnum=0; int dig; scanf("%d%d%d",&n,&k,&p); for(int i=0;i<n;i++) { scanf("%d",&dig); if(dig%2==0) even[evennum++]=dig; else odd[oddnum++]=dig; } if(oddnum<k-p || (oddnum-(k-p))%2!=0) printf("NO\n"); else { if((evennum+(oddnum-(k-p))/2)<p) printf("NO\n"); else { int e=evennum,o=oddnum; printf("YES\n"); int a; for(a=0;a<k-p-1;a++) { printf("1 %d\n",odd[a]);o--; } int j=a; for(int i=0;i<p-1;i++) { if(e>0) { printf("1 %d\n",even[i]); e--; } else { printf("2 %d %d\n",odd[j++],odd[j++]); o-=2; } } if(p!=0&&k-p!=0) { printf("1 %d\n",odd[j]);o--; } printf("%d ",o+e); for(int i=evennum-e;i<evennum;i++) printf("%d ",even[i]); for(int i=oddnum-o;i<oddnum;i++) printf("%d ",odd[i]); printf("\n"); } } return 0; }