求一算法, 请感兴趣的朋友进来看看(200分)

  • 主题发起人 主题发起人 konhon
  • 开始时间 开始时间
K

konhon

Unregistered / Unconfirmed
GUEST, unregistred user!
做假帐时, 按工资算考勤的逆向算法<br><br>请按下面公式算出最合适的X, Y, Z.<br>X * 34 + Y * 6.75 + Z * 9 &nbsp;= Sum<br><br>注: <br>1. X的单位为(天), 可以出现(半天), Y, Z 的在使用的单位为(小时)或(分钟)<br>2. Sum 为已知的任意一整数, &gt; 1000<br><br>要求:<br>1. X的值必须小于或等于用户指定的数, 如果用户指定为23(天), 则X的值必须&lt;=23(天)<br>2. Y + Z 不能大于36(小时)<br>3. Y / 2 &lt; X<br>4. Z / 8 &lt; 4
 
Procedure TForm1.Button1Click(Sender:TObject);<br>Var<br> &nbsp;i, j:Integer;<br> &nbsp;x, sum, sub, OldSub:Double;<br> &nbsp;y, z:Integer;<br> &nbsp;xmax:Integer;<br> &nbsp;rx, ry, rz:Double;<br>Begin<br> &nbsp;sum := 1100; //总金额<br> &nbsp;xmax := 31; //最大天数<br> &nbsp;OldSub := sum;<br><br> &nbsp;x := 0.5;<br> &nbsp;For i := 1 To 31 * 2 Do<br> &nbsp; &nbsp;Begin<br><br> &nbsp; &nbsp; &nbsp;For j := 1 To 36 Do<br> &nbsp; &nbsp; &nbsp; &nbsp;Begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;y := j;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;z := 36 - j;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If ((Y / 2 &gt;= X) Or (Z / 8 &gt;= 4)) Then continue;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sub := sum - x * 34 - y * 6.75 - z * 9;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If Abs(sub) &lt; OldSub Then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OldSub := sub;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rx := x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ry := y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rz := z;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Application.ProcessMessages;<br><br> &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp; &nbsp; &nbsp;x := x + 0.5;<br> &nbsp; &nbsp; &nbsp;If x &gt; xmax Then Break;<br> &nbsp; &nbsp;End;<br><br> &nbsp;//显示结果<br> &nbsp;showmessage(FormatFloat('0.0', rx) + ',' + FormatFloat('0', ry) + ',' + FormatFloat('0', rz) + ',' + FormatFloat('0.0', OldSub));<br>End;
 
結果有負數............
 
Procedure TForm1.Button1Click(Sender:TObject);<br>Var<br> &nbsp;i, j:Integer;<br> &nbsp;x, sum, sub, OldSub:Double;<br> &nbsp;y, z:Integer;<br> &nbsp;xmax:Integer;<br> &nbsp;rx, ry, rz:Double;<br>Begin<br> &nbsp;sum := 1100; //总金额<br> &nbsp;xmax := 31; //最大天数<br> &nbsp;OldSub := sum;<br><br> &nbsp;x := 0.5;<br> &nbsp;For i := 1 To 31 * 2 Do<br> &nbsp; &nbsp;Begin<br><br> &nbsp; &nbsp; &nbsp;For j := 1 To 36 Do<br> &nbsp; &nbsp; &nbsp; &nbsp;Begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;y := j;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;z := 36 - j;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If ((Y / 2 &gt;= X) Or (Z / 8 &gt;= 4)) Then continue;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sub := sum - x * 34 - y * 6.75 - z * 9;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if sub &lt;0 then &nbsp;Continue;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If sub &lt; OldSub Then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OldSub := sub;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rx := x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ry := y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rz := z;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Application.ProcessMessages;<br><br> &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp; &nbsp; &nbsp;x := x + 0.5;<br> &nbsp; &nbsp; &nbsp;If x &gt; xmax Then Break;<br> &nbsp; &nbsp;End;<br><br> &nbsp;//显示结果<br> &nbsp;showmessage(FormatFloat('0.0', rx) + ',' + FormatFloat('0', ry) + ',' + FormatFloat('0', rz) + ',' + FormatFloat('0.0', OldSub));<br>End;
 
楼主分多啊。一问题3问[:D]
 
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=3592354已答
 
socid<br>按你的計算出來, 不符合題目要求喲.
 
我没对结果做太多的校核,只是希望提供一种思路。<br>你的要求:<br>1. X的值必须小于或等于用户指定的数, 如果用户指定为23(天), 则X的值必须&lt;=23(天)<br>=========== &nbsp;这条是满足的<br> Ix := StrToInt(FormatFloat('0', X*2)); // 以半天为单位,所以是2X downto 1<br> &nbsp;for Countx := Ix Downto 1 do &nbsp;<br><br>2. Y + Z 不能大于36(小时)<br>==============这个没问题吧<br> &nbsp; &nbsp; &nbsp; &nbsp;if (Z+Y)&gt;=36 then Continue;<br>3. Y / 2 &lt; X<br>=========== &nbsp;这条也是满足 &nbsp;y/2&lt;x &nbsp;---&gt; y&lt;2x<br> &nbsp; for Y := StrToInt(FormatFloat('0', X*2)) Downto 1 do<br>4. Z / 8 &lt; 4 &nbsp;<br>=========== &nbsp;同样: &nbsp;z/8&lt;4 &nbsp;---&gt; x&lt;32<br> &nbsp; &nbsp; &nbsp;for Z := 32 downto 1 do<br><br>我的想法是尽量排除不合要求的数值计算,减少运算次数
 
Procedure TForm1.Button1Click(Sender:TObject);<br>Var<br> &nbsp;i, j, k:Integer;<br> &nbsp;x, sum, sub, OldSub:Double;<br> &nbsp;y, z:Integer;<br> &nbsp;xmax:Integer;<br> &nbsp;rx, ry, rz:Double;<br>Begin<br> &nbsp;sum := 1100; //总金额<br> &nbsp;xmax := 31; //最大天数<br> &nbsp;OldSub := sum;<br><br> &nbsp;x := 0.5;<br> &nbsp;For i := 1 To 31 * 2 Do<br> &nbsp; &nbsp;Begin<br> &nbsp; &nbsp; &nbsp;For j := 1 To 36 Do<br> &nbsp; &nbsp; &nbsp; &nbsp;For K := 1 To 36 Do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;y := j;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;z := K;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If Y + Z &gt; 36 Then Continue;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If Y / 2 &gt;= X Then Continue;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If Z / 8 &gt;= 4 Then continue;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sub := sum - x * 34 - y * 6.75 - z * 9;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If sub &lt; 0 Then Continue;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If sub &lt; OldSub Then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OldSub := sub;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rx := x;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ry := y;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rz := z;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Application.ProcessMessages;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp; &nbsp; &nbsp;x := x + 0.5;<br> &nbsp; &nbsp; &nbsp;If x &gt; xmax Then Break;<br> &nbsp; &nbsp;End;<br><br> &nbsp;//显示结果<br> &nbsp;showmessage('X:' + FormatFloat('0.0', rx) + #10 + 'Y:' + FormatFloat('0', ry) + #10 + 'Z:' + FormatFloat('0', rz) + #10 + 'DISTANCE:' + FormatFloat('0.00', OldSub));<br>End;
 
后退
顶部