C题:
思路很简单。
由题意可知,奇数的集合有k-p个,偶数的几何有p个。
那么我们先选择k-p-1个奇数,每一个奇数是一个集合。
然后我们再选择p个偶数,每一个偶数是一个集合,如果偶数的个数不足,那么就用两个奇数去补。
然后我们再把剩下的所有的数放在一个集合里。
By rowanhao, contest: Codeforces Round #251 (Div. 2), problem: (C) Devu and Partitioning of the Array, Accepted, #
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define LL __int64
#define maxn 330000
vector<int>vec;
int a[maxn];
int vis[maxn];
int main()
{
int n,k,p;
while(~scanf("%d%d%d",&n,&k,&p))
{
int sum=0;
int q=k-p;
int l,r;
l=r=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]%2)
{
sum++;
if(r<q)r++;
else l+=1;
}
else l+=2;
}
memset(vis,0,sizeof(vis));
if(r==q&&l>=p*2&&l%2==0)
{
l=p;
cout<<"YES"<<endl;
if(p==0)r--;
for(int i=1;i<=n;i++)
{
if(a[i]%2&&r)
{
r--;
printf("1 %d\n",a[i]);
vis[i]=1;
}
if(a[i]%2==0&&l>1)
{
vis[i]=1;
l--;
printf("1 %d\n",a[i]);
}
}
vec.clear();
for(int i=1;i<=n;i++)
{
if(vis[i])continue;
vec.push_back(a[i]);
if(l>1&&vec.size()==2)
{
printf("2 %d %d\n",vec[0],vec[1]);
vec.clear();
l--;
}
}
if(vec.size()==0)continue;
printf("%d",vec.size());
for(int i=0;i<vec.size();i++)printf(" %d",vec[i]);
puts("");
}
else cout<<"NO"<<endl;
}
return 0;
}
D题:
思路也挺简单的。
由题意可知,我们需要把a数组的所有的数都变的大于等于x。b数组里的所有的数都小于等于x。
x是a数组和b数组中的某一个数。
那么我们枚举x,然后二分查找。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
#define LL __int64
#define maxn 220100
double num[maxn];
vector<LL>vec;
LL a[maxn];
LL b[maxn];
LL sa[maxn];
LL sb[maxn];
LL n,m;
LL dos(LL x)
{
LL sum=0;
LL l,r,mid;
l=1;r=n+1;mid=(l+r)/2;
while(l<r)
{
if(a[mid]>=x)r=mid;
else l=mid+1;
mid=(l+r)/2;
}
sum+=(mid-1)*x-sa[mid-1];
l=1;r=m+1;mid=(l+r)/2;
while(l<r)
{
if(b[mid]>=x)r=mid;
else l=mid+1;
mid=(l+r)/2;
}
sum+=sb[mid]-(m-mid+1)*x;
return sum;
}
int main()
{
while(~scanf("%I64d%I64d",&n,&m))
{
for(LL i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
vec.push_back(a[i]);
}
for(LL i=1;i<=m;i++)
{
scanf("%I64d",&b[i]);
vec.push_back(b[i]);
}
sort(a+1,a+n+1);
sort(b+1,b+m+1);
sort(vec.begin(),vec.end());
memset(sa,0,sizeof(sa));
memset(sb,0,sizeof(sb));
for(LL i=1;i<=n;i++)sa[i]=sa[i-1]+a[i];
for(LL i=m;i>=1;i--)sb[i]=sb[i+1]+b[i];
LL minn=-1;
for(LL i=0;i<vec.size();i++)
{
LL x=vec[i];
if(minn==-1)minn=dos(x);
else minn=min(minn,dos(x));
}
cout<<minn<<endl;
}
return 0;
}