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

K

konhon

Unregistered / Unconfirmed
GUEST, unregistred user!
做假帐时, 按工资算考勤的逆向算法
请按下面公式算出最合适的X, Y, Z.
X * 34 + Y * 6.75 + Z * 9 = Sum
注:
1. X的单位为(天), 可以出现(半天), Y, Z 的在使用的单位为(小时)或(分钟)
2. Sum 为已知的任意一整数, > 1000
要求:
1. X的值必须小于或等于用户指定的数, 如果用户指定为23(天), 则X的值必须<=23(天)
2. Y + Z 不能大于36(小时)
3. Y / 2 < X
4. Z / 8 < 4
 
Procedure TForm1.Button1Click(Sender:TObject);
Var
i, j:Integer;
x, sum, sub, OldSub:Double;
y, z:Integer;
xmax:Integer;
rx, ry, rz:Double;
begin
sum := 1100;
//总金额
xmax := 31;
//最大天数
OldSub := sum;
x := 0.5;
For i := 1 To 31 * 2do
begin

For j := 1 To 36do
begin
y := j;
z := 36 - j;
If ((Y / 2 >= X) Or (Z / 8 >= 4)) then
continue;
sub := sum - x * 34 - y * 6.75 - z * 9;
If Abs(sub) < OldSub then
begin
OldSub := sub;
rx := x;
ry := y;
rz := z;
end;
Application.ProcessMessages;
end;
x := x + 0.5;
If x > xmax then
Break;
end;

//显示结果
showmessage(FormatFloat('0.0', rx) + ',' + FormatFloat('0', ry) + ',' + FormatFloat('0', rz) + ',' + FormatFloat('0.0', OldSub));
end;
 
結果有負數............
 
Procedure TForm1.Button1Click(Sender:TObject);
Var
i, j:Integer;
x, sum, sub, OldSub:Double;
y, z:Integer;
xmax:Integer;
rx, ry, rz:Double;
begin
sum := 1100;
//总金额
xmax := 31;
//最大天数
OldSub := sum;
x := 0.5;
For i := 1 To 31 * 2do
begin

For j := 1 To 36do
begin
y := j;
z := 36 - j;
If ((Y / 2 >= X) Or (Z / 8 >= 4)) then
continue;
sub := sum - x * 34 - y * 6.75 - z * 9;
if sub <0 then
Continue;
If sub < OldSub then
begin
OldSub := sub;
rx := x;
ry := y;
rz := z;
end;
Application.ProcessMessages;
end;
x := x + 0.5;
If x > xmax then
Break;
end;

//显示结果
showmessage(FormatFloat('0.0', rx) + ',' + FormatFloat('0', ry) + ',' + FormatFloat('0', rz) + ',' + FormatFloat('0.0', OldSub));
end;
 
edit2放指定天数, Edit3放指定工资数
var
X, SCalc, rX, RS: Single;
Ix, Y, Z, Sum, rY, rZ, CountX: Integer;
begin
X := StrToFloat(Edit2.Text);
Sum := StrToInt(Edit3.Text);
Ix := StrToInt(FormatFloat('0', X*2));
RS := 1000;
for Countx := Ixdo
wnto 1do
begin
for Y := StrToInt(FormatFloat('0', X*2))do
wnto 1do
begin
for Z := 32do
wnto 1do
begin
if (Z+Y)>=36 then
Continue;
SCalc := Sum-(34*X+6.75*Y+9*Z);
If Abs(SCalc) < Abs(RS) then
begin
RS := SCalc;
rx := x;
ry := y;
rz := z;
end;
X := X-0.5;
end;
end;
end;
ShowMessage('X:'+FormatFloat('0.0',RX)+' Y:'+IntToStr(RY)+' Z:'+IntToStr(RZ)+' Dif:'+FormatFloat('0.0',RS));
end;
 
socid
按你的計算出來, 不符合題目要求喲.
 
Procedure TForm1.Button1Click(Sender:TObject);
Var
i, j, k:Integer;
x, sum, sub, OldSub:Double;
y, z:Integer;
xmax:Integer;
rx, ry, rz:Double;
begin
sum := 1100;
//总金额
xmax := 31;
//最大天数
OldSub := sum;
x := 0.5;
For i := 1 To 31 * 2do
begin
For j := 1 To 36do
For K := 1 To 36do
begin
y := j;
z := K;
If Y + Z > 36 then
Continue;
If Y / 2 >= X then
Continue;
If Z / 8 >= 4 then
continue;
sub := sum - x * 34 - y * 6.75 - z * 9;
If sub < 0 then
Continue;
If sub < OldSub then
begin
OldSub := sub;
rx := x;
ry := y;
rz := z;
end;
Application.ProcessMessages;
end;
x := x + 0.5;
If x > xmax then
Break;
end;

//显示结果
showmessage('X:' + FormatFloat('0.0', rx) + #10 + 'Y:' + FormatFloat('0', ry) + #10 + 'Z:' + FormatFloat('0', rz) + #10 + 'DISTANCE:' + FormatFloat('0.00', OldSub));
end;
 
以下代码不知能否满足:

procedure TForm1.Button1Click(Sender: TObject);
var sum,y,z:integer;
x:real;
begin

sum:=strtoint(edit1.Text );
// 已知的任意整数 如1000
x:=strtofloat(edit2.Text );
//于用户指定的天数 如23
while x>=0.5do
begin
for y:=1 to 35do
for z:=1 to 36-ydo
if (x>y/2) and (z<32) and (x*34+y*6.75+z*9=sum) then
begin
showmessage('x='+formatfloat('0.#',x));
showmessage('y='+inttostr(y));
showmessage('z='+inttostr(z));
exit;
end;
x:=x-0.5;
end;
if x<0.5 then
showmessage('没有满足条件的X/Y/Z');
end;

如果 SUM=1000,x=23 则输出为
x=22
y=4
z=25
 
楼上的
x*34+y*6.75+z*9=sum 这个 条件 是不对 的
 
&quot;楼上的
x*34+y*6.75+z*9=sum 这个 条件 是不对 的
&quot;── 为什么不对啊?
 
必须要有 x,y,z 而不是 没有满足条件的X/Y/Z
如果 我 指定 x必须 小于 20,就 没有 答案 了
 
不知道是不是楼主要的答案
X, Y, Z,sum的结果为:
21.5,4,27,1001
 
忘把程序贴出来了
各位不好意思了啊!
var
sum:Integer;
x1:Real;
y1,z1:Integer;
begin
for sum:=1001 to 2001do
begin
x1:=1;
while x1<=31do
begin
for y1:=1 to 24do
begin
if ((y1 / 2) >=x1) then
Continue;
for z1:=1 to 60do
begin
if ((y1 + z1)< 36) and ((z1 / 8) <4) then
begin
if X1 * 34 + Y1 * 6.75 + Z1 * 9 = Sum then
begin
ShowMessage(''+floattostr(x1)+','+inttostr(y1)+','+inttostr(z1)+','+inttostr(SUM)+'');
Exit;
end else
begin
mmo1.Lines.Add(''+floattostr(x1)+','+inttostr(y1)+','+inttostr(z1)+','+inttostr(SUM)+'');
end;
end else
Continue;
end;
//end for
end;
//end for
x1:=x1+0.5;
end;
//end while
end;
//end for
ShowMessage('程序运算结束!');
end;
 

Similar threads

S
回复
0
查看
740
SUNSTONE的Delphi笔记
S
S
回复
0
查看
619
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
950
SUNSTONE的Delphi笔记
S
顶部