Codeforces 439C Devu and Partitioning of the Array

题目链接:http://codeforces.com/contest/439/problem/C


题意:给出n个数,要求将其分为k份,k有p份之和是偶数,p-k份之和是奇数,给出分配方案


思路:2个奇数可以组成一个偶数,一个奇数一个偶数可以组成一个奇数,这样构造就行,一开始用数组保存方案数,结果超内存了,后来直接构造好就输出,最后一组数的和可能要求是奇数也可能要求是偶数,所以奇数和偶数先保留一位不进行输出


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;

int s[100030];
int odd[100030],even[100030];

int main()
{
    int n,k,p;
    while (scanf("%d%d%d",&n,&k,&p)!=EOF)
    {
        memset(odd,0,sizeof(odd));
        memset(even,0,sizeof(even));
        int cnt1=0,cnt2=0;
        for (int i=0;i<n;i++)
        {
          scanf("%d",&s[i]);
          if (s[i]%2==0)
          {
              even[cnt2++]=s[i];
          }
          else
          {
              odd[cnt1++]=s[i];
          }
        }

        if (cnt1<k-p || (cnt1-k+p)%2==1 || (cnt1-k+p)/2+cnt2<p)
        {
            printf("NO\n");
        }
        else
        {
            cout<<"YES"<<endl;
            for (int i=0;i<k-p-1;i++)
            {
                cout<<"1 "<<odd[cnt1-1]<<endl;
                cnt1--;
            }

            for (int i=0;i<p-1;i++)
            {
                if (cnt2>0)
                {
                    cout<<"1 "<<even[cnt2-1]<<endl;
                    cnt2--;
                }
                else if (cnt1>=2)
                {
                    cout<<"2 "<<odd[cnt1-1]<<" "<<odd[cnt1-2]<<endl;
                    cnt1=cnt1-2;
                }

            }

            if (k-p && p)
            cout<<"1 "<<odd[--cnt1]<<endl;
            if (cnt2+cnt1>0)
            {
                cout<<cnt2+cnt1;
                for (int i=0;i<cnt1;i++)
                {
                    cout<<" "<<odd[i];
                }
                for (int i=0;i<cnt2;i++)
                {
                    cout<<" "<<even[i];
                }
                cout<<endl;
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值