//将一个集合分为两个集合,两个子集合的交为空集,并为原集合,
//两个子集合元素个数之差尽可能的小,两个子集合的各自元素之和的差尽可能大
#include<cstdio>
#include<cstdlib>
#include<time.h>
#include<math.h>
#include<iostream>
using namespace std;
//对区间[left,right]进行随机划分
int randPartition(int A[], int left, int right) {
int p = (round(1.0 * rand() / RAND_MAX * (right - left) + left));
swap(A[p], A[left]);
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;
}
int randSelect(int A[], int left, int right, int K) {
if (left == right) return A[left];
int p = randPartition(A, left, right);
int M = p - left + 1;
if (K == M) return A[p];
if (K < M) {
return randSelect(A, left, p - 1, K);
}
else {
return randSelect(A, p + 1, right, K - M);
}
}
const int maxn=100010;
int A[maxn],n;
int main() {
srand((unsigned)time(NULL));
int sum=0,sum1=0;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d", &A[i]);
sum+=A[i];
}
randSelect(A,0,n-1,n/2);
for(int i=0;i<n/2;++i){
sum1+=A[i];
}
printf("%d\n", (sum-sum1)-sum1);
return 0;
}
随机选择算法
最新推荐文章于 2021-11-30 22:33:23 发布