演算法二十二:陣列和之間差最小
有兩個序列a,b,大小都為n,序列元素的值任意整數,無序;
要求:通過交換a,b中的元素,使[序列a元素的和]與[序列b元素的和]之間的差最小。
例如:
var a=[100,99,98,1,2, 3];
var b=[1, 2, 3, 4,5,40];
分析:要是序列的和之差最小,考慮將兩個序列組合成一個序列1,對序列求和sum,選取一個數組,使得這個陣列的和最接近sum/2,對合成序列1求和,然後取均值,再進行選取那些與這個均值最接近的序列1中的數,放入序列a中,這樣可以使得陣列和最近進sum/2。
程式碼:
MinMinus.h
#ifndef MINMINUS_CPP
#define MINMINUS_CPP
#include< iostream>;
#include< vector>;
#include <math.h>
using namespace std;
void MinMinus(int n,int c[]);
int extractmin(vector<double> ivec,vector<bool> visited);
#endif
MinMinus.cpp
#include "MinMinus.h"
void MinMinus(int n,int c[]){
vector<int> a,b;
int sum=0;
vector<double> ivec;
vector<bool> visited;
int k;
int index=0;
double ave;
for(int i=0;i<2*n;i++){
sum += c[i];
}
ave = (double)sum/(2*n);
for(int i=0;i<2*n;i++){
ivec.push_back(c[i]-ave);
visited.push_back(false);
}
for(int i=0;i<n;i++){
k = extractmin(ivec,visited);
a.push_back(c[k]);
visited[k] = true;
}
for(int i=0;i<2*n;i++){
if(visited[i]==false){
b.push_back(c[i]);
visited[i] = true;
}
}
for(int i=0;i<n;i++){
cout<<a[i]<<"\t";
}
cout<<endl;
for(int i=0;i<n;i++){
cout<<b[i]<<"\t";
}
}
int extractmin(vector<double> ivec,vector<bool> visited){
int k;
int i;
for(i=0;(i<ivec.size())&&(visited[i]==true);i++);
k = i;
for(;i<ivec.size();i++){
if((fabs(ivec[i])<fabs(ivec[k]))&&(visited[i]==false)){
k = i;
}
}
return k;
}