大家进来,看看这是算法怎么编程?(100分)

  • 主题发起人 主题发起人 黑暗法师
  • 开始时间 开始时间

黑暗法师

Unregistered / Unconfirmed
GUEST, unregistred user!
1,2,3,4,5,6,7,8,9,10,11…………我想求任意几个数相加得30,看看有几组,再将这几组数分别输出?大家看有什么办法?怎么编码?
 
procedure TForm1.SetIt(m:integer);
var
a:array[1..30]of integer;
i,j,t,r,k,n,m,step:integer;
begin
n:=30;
t:=1;step:=0;
for j:=1 to m do begin
a[j]:=0;
while t>0 do begin
a[t]:=a[t]+1;
if a[t]>n then t:=t-1
else begin
r:=0;
for i:=1 to t-1 do
if a[t]=a then r:=100;
if r<>100 then begin
if t=m then begin
step:=step+1;
for k:=1 to t do begin
if k=1 then SL.Add('');
SL[SL.Count-1]:=SL[SL.Count-1]+' '+inttostr(a[k]);
end;
end;
if t<m then begin
//t:=t+1;a[t]:=0; {将a[t]:=0改为a[t]:=a[t-1],则为组合}
t:=t+1;a[t]:=a[t-1];
end;
end;
end;
end;
end;
end;
调用方式为:
procedure TForm1.Button1Click(Sender: TObject);
begin
if SL<>nil then FreeAndNil(SL);
SL:=TStringList.Create;
SetIt(3);
memo1.Text:=SL.CommaText;
end;
这是从30个数中任意取3个的算法,你可以自己循环任意取1到30个,然后相加判断其和,就是傻了一点,不过你可以按照一定的顺序判断,一旦和超过30就退出
 
我要的任意多个数相加的和,不仅仅是3个数的和,再说你这种算法不太好,如果数多的话,运行可能会影响运算速度,楼上的再想想有什么更好的方法,多谢你支持!
 
数字允许重复吗?还是只能使用不重复的数字?
 
1、1加到8=36>30,所以最多只有7个数字相加
2、规律:
1个数字:30=30/1
2个数字:15=30/2=》从16到29,必有1个小于15的数字匹配,即必有1个满足条件的数字
3个数字:10=30/3=》30-N(>=10),必有2个满足条件的数字
4个数字:7=30/4=》必有3个满足条件的数字
5个数字:6=30/5=》必有4个满足条件的数字
6个数字:5=30/6=》必有5个满足条件的数字
7个数字:4=30/7=》必有6个满足条件的数字
假设求N个数字之和等于30的组合,NA表示从1到N-1的和,NB表示不小于30除以N的最小整数(即求整再加1),那么第一次循环为:
for i:=NB to 30-NA do 。。。
所以算法为:
private
SL:TStringList;
function MyCal(He:Integer;//和值
N:Integer //可加次数
):TStringList;

function TForm1.MyCal(He:Integer;//和值
N:Integer //可加次数
):TStringList;
var i,HeMin,iDiv,NA,NB:Integer;
SL_Sub:TStringList;
begin
Result:=TStringList.Create;
SL_Sub:=TStringList.Create;
HeMin:=0;
iDiv:=(He Div N)+1;
for i:=1 to N-1 do HeMin:=HeMin+i;
for i:=iDiv to He-HeMin do begin
if N=2 then begin
Result.Add(inttostr(i)+','+inttostr(He-i));
end else begin
SL_Sub:=MyCal(He-i,N-1);
Result.Add(inttostr(i)+',('+SL_Sub.CommaText+')');
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var SL_Sub:TStringList;
begin
SL_Sub:=MyCal(30,strtoint(Edit1.Text));
ListBox1.Items:=SL_Sub;
end;
那么你只要求出从N=2到N=7的就可以了,具体结果你自己必须还需要重新整理一下,完工了展示一下好不好!
 
7 1+2+3+4+5+6=21 max=9 C9n7= 36
6 1+2+3+4+5=15 Max=16 C16N6=8008
5 1+2+3+4=10 max=20 C20n5=15504
4 1+2+3=6 max=24 C24n4=10626
3 1+2=3 max=27 C27n3=2925
2 1=1 max=29 C29n2=406
1 max=30 C30n1=30

所有这些组合只有30000左右 穷举法也不要多少时间!用循环穷举就6重循环
 
增强版:

function TForm1.MyCal(He:Integer;//和值
N:Integer; //可加次数
StrPre:String=''):TStringList;
var i,HeMin,iDiv,NA,NB:Integer;
SL_Sub:TStringList;
S:String;
begin
Result:=TStringList.Create;
SL_Sub:=TStringList.Create;
HeMin:=0;
iDiv:=(He Div N)+1;
if StrPre='' then S:=''
else S:=StrPre+',';
for i:=1 to N-1 do HeMin:=HeMin+i;
for i:=iDiv to He-HeMin do begin
if N=2 then begin
Result.Add(S+inttostr(i)+','+inttostr(He-i));
end else begin
SL_Sub:=MyCal(He-i,N-1,StrPre+','+inttostr(i));
Result.Add(S+inttostr(i)+',('+SL_Sub.CommaText+')');
end;
end;
end;
procedure TForm1.MyCalculate(Source:String;SL:TStringList);
var SL_Sub:TStringList;
i,iPos,jPos1,jPos2:Integer;
S:String;
begin
iPos:=Pos('(',Source);
if iPos=0 then begin
SL.Add(Source);
exit;
end;
SL_Sub:=TStringList.Create;
S:=Source;
while iPos>0 do begin
S:=Copy(S,iPos+1,Length(S));
jPos1:=Pos('(',S);
jPos2:=Pos(')',S);
if jPos2=0 then Break;
if jPos1=0 then begin
SL.Add(Copy(S,1,jPos2-1));
exit;
end else begin
if jPos2<jPos1 then begin
SL.Add(Copy(S,1,jPos2-1));
S:=Copy(S,jPos2+1,Length(S));
end else
S:=Copy(S,jPos1+1,Length(S));
end;
end;
end;

procedure Splite(s,SpliteStr:string;L:TStringlist);
Var I:INTEGER;
begin
l.Clear;
i:=pos(SpliteStr,s);
while i>0 do begin
L.Add(copy(s,1,i-1));
delete(s,1,i);
i:=pos(SpliteStr,s);
end;
L.Add(s);
end;
function JudgeDupli(Source:String):Boolean;
var i,j1,j2,j3:Integer;
SL:TStringList;
S,SV:String;
begin
SL:=TStringList.Create;
Splite(Source,',',SL);
S:=','+stringreplace(Source,',',',,',[rfReplaceAll])+',';
for i:=0 to SL.Count-1 do begin
SV:=','+SL+',';
SV:=StringReplace(S,SV,'',[rfReplaceAll]);
j1:=Length(S);
j2:=Length(','+SL+',');
j3:=Length(SV);
if j1-j2>j3 then begin
Result:=True;
exit;
end;
end;
Result:=False;
end;
function ReturnFormat(Source:String):String;
var i:Integer;
S:String;
begin
S:=stringreplace(Source,'"','',[rfReplaceAll]);
while Copy(S,1,1)=',' do
S:=Copy(S,2,Length(S));
while Copy(S,Length(S),1)=',' do
S:=Copy(S,1,Length(S)-1);
if JudgeDupli(S) then Result:=''
else Result:=S;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i,j,m:integer;
SL,SL_Return,SL_Value:TStringList;
S:String;
begin
SL:=TStringList.Create;
SL_Return:=TStringList.Create;
SL_Value:=TStringList.Create;
for m:=2 to 7 do begin
SL.Clear;
SL_Return.Clear;
SL_Value.Clear;
SL:=MyCal(30,m);
for i:=0 to SL.Count-1 do
MyCalculate(SL,SL_Return);
for i:=0 to SL_Return.Count-1 do begin
SL.Clear;
Splite(SL_Return,'","',SL);
for j:=0 to SL.Count-1 do begin
S:=ReturnFormat(SL[j]);
if S<>'' then SL_Value.Add(S);
end;
end;
S:='';
for i:=0 to SL_Value.Count-1 do begin
if S='' then S:='('+SL_Value+')'
else S:=S+',('+SL_Value+')';
end;
Memo1.Lines.Add(S);
end;
end;
 
这个递归算法 利用集合数度飞快
type
int30=1..30;
set30=set of int30;
var
Set30s:array of Set30;
function SumSet30(T30:set30):integer;
var
i:integer;
begin
result:=0;
for i:=1 to 30 do
if i in T30 then result:=result+i;
end;

procedure AddSet30(T30:set30);
var
count:integer;
begin
count:=high(Set30s)+2;
setlength(Set30s,count);
set30s[count-1]:=T30;
end;

procedure comx30(mainSet:set30);
var
i:integer;
Snum:integer;
ASet:Set30;
begin
snum:=30-SumSet30(MainSet);
for i:=Snum downto 1 do
begin
if not (i in MainSet) then
begin
Aset:=MainSet+;
if SumSet30(Aset)=30 then AddSet30(Aset)
else comx30(Aset);
end;//end if not (i in mainSet)
end;//for i:=1
end;
调用 comx30([]);
 
最后结果 41867 条
 
有点问题,有重复组合, 我检查一下
 
原因找到了,是递归路径顺序不同造成的(1 2 3,1 3 2),需要在把生成的数据合并一次就好了.
 
递规过程会出现重复情况,可以考虑在AddSet30里修改。
 
好了! 这是结果
30 总计: 30
1 29 总计: 30
2 28 总计: 30
3 27 总计: 30
1 2 27 总计: 30
4 26 总计: 30
1 3 26 总计: 30
5 25 总计: 30
1 4 25 总计: 30
2 3 25 总计: 30
6 24 总计: 30
1 5 24 总计: 30
2 4 24 总计: 30
1 2 3 24 总计: 30
7 23 总计: 30
1 6 23 总计: 30
2 5 23 总计: 30
3 4 23 总计: 30
1 2 4 23 总计: 30
8 22 总计: 30
1 7 22 总计: 30
2 6 22 总计: 30
3 5 22 总计: 30
1 2 5 22 总计: 30
1 3 4 22 总计: 30
9 21 总计: 30
1 8 21 总计: 30
2 7 21 总计: 30
3 6 21 总计: 30
1 2 6 21 总计: 30
4 5 21 总计: 30
1 3 5 21 总计: 30
2 3 4 21 总计: 30
10 20 总计: 30
1 9 20 总计: 30
2 8 20 总计: 30
3 7 20 总计: 30
1 2 7 20 总计: 30
4 6 20 总计: 30
1 3 6 20 总计: 30
1 4 5 20 总计: 30
2 3 5 20 总计: 30
1 2 3 4 20 总计: 30
11 19 总计: 30
1 10 19 总计: 30
2 9 19 总计: 30
3 8 19 总计: 30
1 2 8 19 总计: 30
4 7 19 总计: 30
1 3 7 19 总计: 30
5 6 19 总计: 30
1 4 6 19 总计: 30
2 3 6 19 总计: 30
2 4 5 19 总计: 30
1 2 3 5 19 总计: 30
12 18 总计: 30
1 11 18 总计: 30
2 10 18 总计: 30
3 9 18 总计: 30
1 2 9 18 总计: 30
4 8 18 总计: 30
1 3 8 18 总计: 30
5 7 18 总计: 30
1 4 7 18 总计: 30
2 3 7 18 总计: 30
1 5 6 18 总计: 30
2 4 6 18 总计: 30
1 2 3 6 18 总计: 30
3 4 5 18 总计: 30
1 2 4 5 18 总计: 30
13 17 总计: 30
1 12 17 总计: 30
2 11 17 总计: 30
3 10 17 总计: 30
1 2 10 17 总计: 30
4 9 17 总计: 30
1 3 9 17 总计: 30
5 8 17 总计: 30
1 4 8 17 总计: 30
2 3 8 17 总计: 30
6 7 17 总计: 30
1 5 7 17 总计: 30
2 4 7 17 总计: 30
1 2 3 7 17 总计: 30
2 5 6 17 总计: 30
3 4 6 17 总计: 30
1 2 4 6 17 总计: 30
1 3 4 5 17 总计: 30
14 16 总计: 30
1 13 16 总计: 30
2 12 16 总计: 30
3 11 16 总计: 30
1 2 11 16 总计: 30
4 10 16 总计: 30
1 3 10 16 总计: 30
5 9 16 总计: 30
1 4 9 16 总计: 30
2 3 9 16 总计: 30
6 8 16 总计: 30
1 5 8 16 总计: 30
2 4 8 16 总计: 30
1 2 3 8 16 总计: 30
1 6 7 16 总计: 30
2 5 7 16 总计: 30
3 4 7 16 总计: 30
1 2 4 7 16 总计: 30
3 5 6 16 总计: 30
1 2 5 6 16 总计: 30
1 3 4 6 16 总计: 30
2 3 4 5 16 总计: 30
1 14 15 总计: 30
2 13 15 总计: 30
3 12 15 总计: 30
1 2 12 15 总计: 30
4 11 15 总计: 30
1 3 11 15 总计: 30
5 10 15 总计: 30
1 4 10 15 总计: 30
2 3 10 15 总计: 30
6 9 15 总计: 30
1 5 9 15 总计: 30
2 4 9 15 总计: 30
1 2 3 9 15 总计: 30
7 8 15 总计: 30
1 6 8 15 总计: 30
2 5 8 15 总计: 30
3 4 8 15 总计: 30
1 2 4 8 15 总计: 30
2 6 7 15 总计: 30
3 5 7 15 总计: 30
1 2 5 7 15 总计: 30
1 3 4 7 15 总计: 30
4 5 6 15 总计: 30
1 3 5 6 15 总计: 30
2 3 4 6 15 总计: 30
1 2 3 4 5 15 总计: 30
3 13 14 总计: 30
1 2 13 14 总计: 30
4 12 14 总计: 30
1 3 12 14 总计: 30
5 11 14 总计: 30
1 4 11 14 总计: 30
2 3 11 14 总计: 30
6 10 14 总计: 30
1 5 10 14 总计: 30
2 4 10 14 总计: 30
1 2 3 10 14 总计: 30
7 9 14 总计: 30
1 6 9 14 总计: 30
2 5 9 14 总计: 30
3 4 9 14 总计: 30
1 2 4 9 14 总计: 30
1 7 8 14 总计: 30
2 6 8 14 总计: 30
3 5 8 14 总计: 30
1 2 5 8 14 总计: 30
1 3 4 8 14 总计: 30
3 6 7 14 总计: 30
1 2 6 7 14 总计: 30
4 5 7 14 总计: 30
1 3 5 7 14 总计: 30
2 3 4 7 14 总计: 30
1 4 5 6 14 总计: 30
2 3 5 6 14 总计: 30
1 2 3 4 6 14 总计: 30
5 12 13 总计: 30
1 4 12 13 总计: 30
2 3 12 13 总计: 30
6 11 13 总计: 30
1 5 11 13 总计: 30
2 4 11 13 总计: 30
1 2 3 11 13 总计: 30
7 10 13 总计: 30
1 6 10 13 总计: 30
2 5 10 13 总计: 30
3 4 10 13 总计: 30
1 2 4 10 13 总计: 30
8 9 13 总计: 30
1 7 9 13 总计: 30
2 6 9 13 总计: 30
3 5 9 13 总计: 30
1 2 5 9 13 总计: 30
1 3 4 9 13 总计: 30
2 7 8 13 总计: 30
3 6 8 13 总计: 30
1 2 6 8 13 总计: 30
4 5 8 13 总计: 30
1 3 5 8 13 总计: 30
2 3 4 8 13 总计: 30
4 6 7 13 总计: 30
1 3 6 7 13 总计: 30
1 4 5 7 13 总计: 30
2 3 5 7 13 总计: 30
1 2 3 4 7 13 总计: 30
2 4 5 6 13 总计: 30
1 2 3 5 6 13 总计: 30
7 11 12 总计: 30
1 6 11 12 总计: 30
2 5 11 12 总计: 30
3 4 11 12 总计: 30
1 2 4 11 12 总计: 30
8 10 12 总计: 30
1 7 10 12 总计: 30
2 6 10 12 总计: 30
3 5 10 12 总计: 30
1 2 5 10 12 总计: 30
1 3 4 10 12 总计: 30
1 8 9 12 总计: 30
2 7 9 12 总计: 30
3 6 9 12 总计: 30
1 2 6 9 12 总计: 30
4 5 9 12 总计: 30
1 3 5 9 12 总计: 30
2 3 4 9 12 总计: 30
3 7 8 12 总计: 30
1 2 7 8 12 总计: 30
4 6 8 12 总计: 30
1 3 6 8 12 总计: 30
1 4 5 8 12 总计: 30
2 3 5 8 12 总计: 30
1 2 3 4 8 12 总计: 30
5 6 7 12 总计: 30
1 4 6 7 12 总计: 30
2 3 6 7 12 总计: 30
2 4 5 7 12 总计: 30
1 2 3 5 7 12 总计: 30
3 4 5 6 12 总计: 30
1 2 4 5 6 12 总计: 30
9 10 11 总计: 30
1 8 10 11 总计: 30
2 7 10 11 总计: 30
3 6 10 11 总计: 30
1 2 6 10 11 总计: 30
4 5 10 11 总计: 30
1 3 5 10 11 总计: 30
2 3 4 10 11 总计: 30
2 8 9 11 总计: 30
3 7 9 11 总计: 30
1 2 7 9 11 总计: 30
4 6 9 11 总计: 30
1 3 6 9 11 总计: 30
1 4 5 9 11 总计: 30
2 3 5 9 11 总计: 30
1 2 3 4 9 11 总计: 30
4 7 8 11 总计: 30
1 3 7 8 11 总计: 30
5 6 8 11 总计: 30
1 4 6 8 11 总计: 30
2 3 6 8 11 总计: 30
2 4 5 8 11 总计: 30
1 2 3 5 8 11 总计: 30
1 5 6 7 11 总计: 30
2 4 6 7 11 总计: 30
1 2 3 6 7 11 总计: 30
3 4 5 7 11 总计: 30
1 2 4 5 7 11 总计: 30
1 3 4 5 6 11 总计: 30
3 8 9 10 总计: 30
1 2 8 9 10 总计: 30
4 7 9 10 总计: 30
1 3 7 9 10 总计: 30
5 6 9 10 总计: 30
1 4 6 9 10 总计: 30
2 3 6 9 10 总计: 30
2 4 5 9 10 总计: 30
1 2 3 5 9 10 总计: 30
5 7 8 10 总计: 30
1 4 7 8 10 总计: 30
2 3 7 8 10 总计: 30
1 5 6 8 10 总计: 30
2 4 6 8 10 总计: 30
1 2 3 6 8 10 总计: 30
3 4 5 8 10 总计: 30
1 2 4 5 8 10 总计: 30
2 5 6 7 10 总计: 30
3 4 6 7 10 总计: 30
1 2 4 6 7 10 总计: 30
1 3 4 5 7 10 总计: 30
2 3 4 5 6 10 总计: 30
6 7 8 9 总计: 30
1 5 7 8 9 总计: 30
2 4 7 8 9 总计: 30
1 2 3 7 8 9 总计: 30
2 5 6 8 9 总计: 30
3 4 6 8 9 总计: 30
1 2 4 6 8 9 总计: 30
1 3 4 5 8 9 总计: 30
3 5 6 7 9 总计: 30
1 2 5 6 7 9 总计: 30
1 3 4 6 7 9 总计: 30
2 3 4 5 7 9 总计: 30
1 2 3 4 5 6 9 总计: 30
4 5 6 7 8 总计: 30
1 3 5 6 7 8 总计: 30
2 3 4 6 7 8 总计: 30
1 2 3 4 5 7 8 总计: 30
总共:296 种组合
OK!
 
整个运行时间不到3秒
 
这个个东西居然搞了2个小时,饿死了!我出去觅食了!要演示的留信箱
 
后退
顶部