M
martinwang
Unregistered / Unconfirmed
GUEST, unregistred user!
有三个数字(170,180,215,数字不定),三个数字对应有不同的个数(170的有200个,180的有20个,215的有300个,个数不定),有一总数3648,<br>求:<br> 根据三个数字及对应的个数组合成接近或大于3648最小的数如3648, 3649,列出所有的可能的组合,并将所有组合后每个数字的剩余值求出;<br>注意:<br> 当每计算完一种组合后,每一次都求剩余组合的最小数,反复进行计算求解,直到达不到3648为止!!!!<br> 现有代码:<br> iNum1, iNum2, iNum3: integer;//三个数<br> iCount1, iCount2, iCount3: integer;//三个数的每个的个数 <br> iCountAll: integer;//总数<br>procedure TForm1.btn1Click(Sender: TObject);<br><br><br>const<br> Msg = '当一数值[%s]经过计算的张数为:[%s]';<br> ValueEqual = '发现总数相等情况:数值1[%s](%s), 数值2[%s](%s),数值3[%s](%s)';<br> //ValueEqual = '发现总数相等情况:数值1[%s](%s)(剩余%s), 数值2[%s](%s)(剩余%s),数值3[%s](%s)(剩余%s)';<br>// ValueNotEqual = '发现总数没有相等情况,能获得的最小值是:%s, 数值1[%s](%s)(剩余%s), 数值2[%s](%s)(剩余%s),数值3[%s](%s)(剩余%s)';<br> ValueNotEqual = '发现总数没有相等情况,能获得的最小值是:%s, 数值1[%s](%s), 数值2[%s](%s),数值3[%s](%s)';<br> LeftMsg = '剩余数值1[%s](%s), 数值2[%s](%s), 数值3[%s](%s)';<br>var<br> iCount: integer;//个数<br> Count1, Count2, Count3: Integer;<br> i, j, k: integer;//计数器<br> ls, lsValue: TStringList;<br> iTmp, iMin: integer;<br> bResult: boolean;<br> strTmp: string;<br> iTotal: integer;<br> iTmpTotal: integer;<br>begin<br> try<br> ls := TstringList.Create;<br> lsValue := TStringList.Create;<br> bResult := False;<br> //先计算一个数为主的 <br> mmo1.Lines.Clear;<br> iTotal := iCountAll - StrToIntDef(edt1.Text, 0);<br> iTmpTotal := iCount1 * iNum1 + iCount2 * iNum2 + iCount3 * iNum3;<br> mmo1.Lines.Add('*******************开始计算********************');<br> mmo1.Lines.Add('*******************数值为:' + IntToStr(iCountAll) + '*********');<br> mmo1.Lines.Add('*******************起始值为:' + IntToStr(iTotal) + '*********');<br> iTmp := 0;<br> Count1 := iCount1;<br> Count2 := iCount2;<br> Count3 := iCount3;<br> iMin := 0;<br> while (iTmpTotal > iTotal) do<br> begin<br> ls.Clear;<br> for i := 0 to iCount1 do<br> begin<br> for j := 0 to iCount2 do<br> begin<br> for k := 0 to iCount3 do<br> begin<br> if ((Count1 - i ) < 0 ) or ((Count2 - j ) < 0 ) or ((Count3 - k ) < 0 ) then break;<br><br> iTmp := i * iNum1 + j * iNum2 + k * iNum3;<br><br> //如果有相等的情况<br> Application.ProcessMessages;<br> if iTmp < iTotal then Continue;<br> //if iTmpTotal < iTotal then break;<br> if (Count1 < 0) or (Count2 < 0) or (Count3 < 0) then break;<br><br><br><br> if iTmp = iTotal then<br> begin<br> mmo1.Lines.Add(Format(ValueEqual, [IntToStr(iNum1), IntToStr(i),<br> IntToStr(iNum2), IntToStr(j), IntToStr(iNum3), IntToStr(k)]));<br> bResult := true;<br> iTmpTotal := iTmpTotal - iTmp;<br> Count1 := Count1 - i;<br> Count2 := Count2 - j;<br> Count3 := Count3 - k;<br><br> break;<br> end<br> //当算出的值大于总数时<br> else if (iTmp > iTotal) then<br> begin<br> ls.Sort;<br> if (ls.Count = 0 ) or ((ls.Count > 0) and (StrToInt(ls.Names[0]) >= iTmp)) then//此处最小值取得有问题<br><br> begin<br> ls.Add(IntToStr(iTmp) + '=' + IntToStr(i) + ',' + IntToStr(j) + ',' + IntToStr(k));<br> iTmpTotal := iTmpTotal - iTmp;<br> Count1 := Count1 - i;<br> Count2 := Count2 - j;<br> Count3 := Count3 - k;<br><br> end;<br> break;<br> end;<br> end;<br> end;<br> end;<br> if (ls.Count > 0 ) {and (not bResult)}then<br> begin<br> ls.Sort;<br> lsValue.Delimiter := ',';<br> strtmp := ls.Names[0];<br> for i := 0 to ls.Count - 1 do<br> begin<br> Application.ProcessMessages;<br> lsValue.DelimitedText := ls.ValueFromIndex;<br> if strtmp = ls.Names then<br> begin<br> mmo1.Lines.Add(Format(ValueNotEqual, [ls.Names, IntToStr(iNum1), lsValue.Strings[0],<br> IntToStr(iNum2), lsValue.Strings[1],<br> IntToStr(iNum3), lsValue.Strings[2]]));<br> end<br> else<br> begin<br> Count1 := Count1 + StrToInt(lsValue[0]);<br> Count2 := Count2 + StrToInt(lsValue[1]);<br> Count3 := Count3 + StrToInt(lsValue[2]);<br> iTmpTotal := iTmpTotal + StrToInt(ls.Names);<br> end;<br> end;<br> end;<br> end;<br> mmo1.Lines.Add(Format(LeftMsg, [IntToStr(iNum1), IntToStr(Count1),<br> IntToStr(iNum2), IntToStr(Count2),IntToStr(iNum3), IntToStr(Count3)]));<br> mmo1.Lines.Add('*******************计算完成********************');<br> ShowMessage('计算完成');<br> finally<br> ls.Free;<br> lsValue.Free;<br> end;<br><br><br><br>end;