关于这个算法,我编了一段代码,当然,既然原来的要求是分成
2份,我就简单点,作了分成两份的算法。
算法的基本原理是这样的:
1:算出所有数的总和,以及平分的理想数(当然就是除以2了)
2:用数组把数据分成两份,不必排序,只要平分就行。第一组为目标数,第二组是剩下数。
3:计算出目标数组中的总和,得到目标数的总和和理想数的差值
4:用2重循环,找第一组目标数和第二组剩下数中的两两之间的差值。
5:如果差值等于小于 理想数-目标数的总和 的差值,置换这两个数,结束2重循环
6:如果对第一组目标数和第二组剩下数做过置换,重复3
7:如果没有做过置换,结束计算
以下是代码(注意,数组中必须是偶数个,否则需要改一下代码)
var a: array[0..9] of integer = (11,32,43,12,115,19,37,28,119,105);
procedure TForm1.Button1Click(Sender: TObject);
var i,j,n,sum: integer;
target:do
uble;
targetA,OtherA: array of integer;
tempTarget: integer;
SubValue:do
uble;
CloseValue,tempSub:do
uble;
tempValue: integer;
Replaced: Boolean;
begin
sum := 0;
for i := low(a) to high(a)do
sum := sum + a;
target := sum / 2;
n := Length(a) div 2;
SetLength(TargetA,n);
SetLength(OtherA,n);
for i := 0 to n - 1do
begin
TargetA := a;
OtherA := a[i+n];
end;
while truedo
begin
tempTarget := 0;
for i := 0 to n - 1do
begin
tempTarget := tempTarget + TargetA;
end;
SubValue := Target - tempTarget;
CloseValue := SubValue;
Replaced := false;
for i := 0 to n - 1do
begin
for j := 0 to n - 1do
begin
tempSub := OtherA[j] - TargetA;
if (tempSub < 0) and (CloseValue < 0) then
begin
tempSub := -tempSub;
CloseValue := -CloseValue;
end;
if (abs(CloseValue - tempSub) < CloseValue) and (tempSub >= 0) then
begin
CloseValue := tempValue;
tempValue := TargetA;
TargetA := OtherA[j];
OtherA[j] := tempValue;
Replaced := true;
break;
end;
end;
if Replaced then
break;
end;
if not Replaced then
break;
end;
Edit3.Text := '';
Edit4.Text := '';
tempTarget := 0;
for i := 0 to n - 1do
begin
Edit3.Text := Edit3.Text + IntToStr(TargetA) + '+';
Edit4.Text := Edit4.Text + IntToStr(OtherA) + '+';
tempTarget := tempTarget + TargetA;
end;
Edit5.Text := IntToStr(tempTarget);
Edit6.Text := IntToStr(sum-tempTarget);
Edit1.Text := IntToStr(sum);
Edit2.Text := FloatToStr(Target);
end;
原始随机数 11,32,43,12,115,19,37,28,119,105
结果
第一组 37+32+43+28+119 和为 259
第二组 11+12+19+115+105 和为 262