给定一个由整数组成的集合,集合中的整数各不相同,现在要将它分为两个子集合:
①、这两个子集合的并为原集合、交为空集;
②、同时在两个子集合的元素个数n1与n2之差的绝对值 |n1-n2| 尽可能小的前提下,
要求它们各自的元素之和S1与S2之差的绝对值 |S1-S2| 尽可能大。
求这个 |S1-S2| 等于多少。
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=100010;
//int a[maxn];
//int n;
int randPartition(int a[],int left,int right)
{
int p=round(1.0*rand()/RAND_MAX*(right-left)+left);
swap(a[left],a[p]);
int temp=a[left];
while(left<right)
{
while(left<right&&a[right]>temp) right--;
a[left]=a[right];
while(left<right&&a[left]<=temp) left++; //别忘记等于!
a[right]=a[left];
}
a[left]=temp;
return left;
}
void randSelect(int a[],int left,int right,int k)
{
if(left==right) return;
int p=randPartition(a,left,right);
int m=p-left+1;
if(m==k) return;
else if(m<k) randSelect(a,p+1,right,k-m);
else randSelect(a,left,p-1,k);
}
int main()
{
srand((unsigned)time(NULL));
int sum=0;
int sum1=0;
int n;
int a[maxn]={0};
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
}
randSelect(a,0,n-1,n/2);
/*
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
*/
for(int i=0;i<n/2;i++) //左边(小的那一堆)n/2个元素
{
sum1+=a[i];
}
cout<<(sum-sum1-sum1)<<endl;
return 0;
}

4315



被折叠的 条评论
为什么被折叠?



