求解(不知道怎么描述)!!!(100分)

  • 主题发起人 主题发起人 阿九
  • 开始时间 开始时间

阿九

Unregistered / Unconfirmed
GUEST, unregistred user!
例:
k:= 3
100--0--0
99--1--0
99--0--1
98--2--0
98--1--1
98--0--2
97--3--0
97--2--1
97--1--2
97--0--3

k:=4
100--0--0--0
99--1--0--0
99--0--1--0
99--0--0--1
98--2--0--0
98--1--1--0
98--1--0--1
98--0--2--0
98--0--1--1
98--0--0--2
97--3--0--0
97--2--1--0
97--2--0--1
97--1--2--0
97--1--1--1
97--1--0--2
97--0--3--0
97--0--2--1
97--0--1--2
97--0--0--3
上述每行的k(k=3和4)个数相加都等于100,列出的是100到97的所有组合。
求解:k个数从100到0的所有组合
 
两重循环搞定
 
上述每行的k(k=3)个数相加都等于100,列出的是100到97的所有组合。
求解:k个数从100到0的所有组合
 
来自:lich, 时间:2006-1-17 12:54:05, ID:3331600
两重循环搞定

现在k是未知的,
 
这是我之前问的一个问题。也是求和的问题,目的是将1,2,4,5,8中随机组合得到20(允许重复)。可能对你有用!
program Project2;

{$APPTYPE CONSOLE}

const
Data: array [1..5] of Integer = (1, 2, 4, 5, 8);

type
TNode = record
Sum: Integer;
d: Integer
end;

var
Stack: array [1..10] of TNode;
Top: Integer;
Sum: Integer;
Count: Integer;

procedure Print;
var
i: Integer;
begin
Inc(Count);
Write(Count, ': ');
for i:=1 to Top-1 do
Write(Data[Stack.d], ' ');
WriteLn
end;

begin
Stack[1].Sum:=0;
Stack[1].d:=0;
Top:=1;
Count:=0;

while Top>0 do
begin
while Stack[Top].d<5 do
begin
Inc(Stack[Top].d);
Sum:=Stack[Top].Sum+Data[Stack[Top].d];
if (Sum<=20) and (Top<=8) then
begin
Inc(Top);
Stack[Top].Sum:=Sum;
Stack[Top].d:=Stack[Top-1].d-1;
if Sum=20 then
Print
end
end;
Dec(Top)
end;
ReadLn
end.

上DFW上的一个朋友给我的!
 
這個更符合樓主要求
unit u_SumEx;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
Tf_SumEx = class(TForm)
Memo1: TMemo;
Panel1: TPanel;
edtSize: TEdit;
Button2: TButton;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
procedure InitArray(iSize: Integer);
procedure SumSum(iOutSize, iTmpSize, iConst: Integer);
public
{ Public declarations }
end;
var
f_SumEx: Tf_SumEx;
aSub: array of Integer;
a: array of array of Integer;
strList:TStrings;
implementation
{$R *.dfm}
procedure Tf_SumEx.SumSum(iOutSize, iTmpSize, iConst: Integer);
var
i, j, k, TmpSize: Integer;
s: string;
iSum: Integer;
begin
if iOutSize > iConst then exit;
for i := iOutSize to 100 do
begin
for j := 0 to iConst - 1 do
begin
aSub[iTmpSize] := a[j];
end;

TmpSize := iTmpSize + 1;
iSum := 0;

if TmpSize >= iConst then
begin
s := '';

for k := 0 to iConst - 1 do
begin
iSum := iSum + aSub[k];
s := s + IntToStr(asub[k]) + ' ';
end;

if iSum = 100 then
strList.Add(s);
end
else
SumSum(iOutSize, TmpSize, iConst);
end;
end;

procedure Tf_SumEx.InitArray(iSize: Integer);
var
i, j: Integer;
begin
SetLength(a, 101, iSize)
//100:Col iSize:Row
for i := 0 to 100 do
begin
for j := 0 to iSize - 1 do
begin
a[j] := i;
end;
end;
end;

procedure Tf_SumEx.Button2Click(Sender: TObject);
var
iSize: Integer;
begin
strList:=TStringList.Create
//用StringList在內存中操作,速度快
try
iSize := StrToInt(edtSize.text);
InitArray(iSize)
//set length array of array of
SetLength(aSub, iSize)
//100:Col iSize:Row
Screen.Cursor:=crHourGlass;
SumSum(0, 0, iSize);
strList.SaveToFile('c:/kkkaaa.txt');
Memo1.Lines.Assign(strList);
finally
strList.Free;
Screen.Cursor:=crDefault;
end;
end;

end.
 
谢谢BrainYang及楼上的各位,BrainYang的方法就可以,我再结合程序把效率提高一下。
 
多人接受答案了。
 
樓主,這個更好玩。用線程,不需要等待
unit u_SumEx;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
Tf_SumEx = class(TForm)
Panel1: TPanel;
edtSize: TEdit;
btnRunThread1: TButton;
Panel2: TPanel;
Memo1: TMemo;
Splitter1: TSplitter;
Memo2: TMemo;
btnRunThread2: TButton;
btnStopThread1: TButton;
lblArrayLength: TLabel;
lblMinValue: TLabel;
lblMaxValue: TLabel;
edtMinValue: TEdit;
edtMaxValue: TEdit;
lblResult: TLabel;
edtResult: TEdit;
procedure btnRunThread1Click(Sender: TObject);
procedure btnRunThread2Click(Sender: TObject);
procedure btnStopThread1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TSumThread=class(TThread)
private
FSub:array of Integer;
FLength:Integer;
FMin:Integer;
FMax:Integer;
FTmpSize:Integer;
FStrSum:String;
FStrList:TStrings;
FMemo:TMemo;
FResult:Integer;
procedure SumSum(iTmpSize:Integer)
//參數可以不要,而用私有變量代替嗎
procedure UpdateMemo;
public
constructor create(iLength,iMin,iMax,iResult:Integer;AMemo:TMemo);
destructor Destroy
override;
procedure execute;override;
end;

var
f_SumEx: Tf_SumEx;
ThreadOne:TSumThread;
ThreadTwo:TSumThread;
implementation

{$R *.dfm}
{ TSumThread }
constructor TSumThread.create(iLength, iMin, iMax,iResult: Integer;AMemo:TMemo);
begin
FLength:=iLength;
FMin:=iMin
//取值范圍最小值,如0
FMax:=iMax
//取值范圍最小值,如100
SetLength(Fsub,iLength);
FTmpSize:=0;
FStrList:=TStringList.Create;
FMemo:=AMemo
//指定在哪個Memo中顯示結果
FResult:=iResult
//結果等于多少時才顯示
inherited Create(False);
end;

destructor TSumThread.Destroy;
begin
FStrList.SaveToFile('c:/kkkaaa.txt')
//可惜只能得到最后一個線程的全部結果
FStrList.Free;
inherited;
end;

procedure TSumThread.execute;
begin
FreeOnTerminate:=True;
if FMin*FLength<=FResult then //小于或等于才開始,三個最小值不可能大于FResult
SumSum(FTmpSize);
end;

procedure TSumThread.SumSum(iTmpSize:Integer);
var
i, j, k: Integer;
s: string;
iSum: Integer;
begin
//這里的FOutSize和FTmpSize可分別用過程局部變量代替
//不過似乎顯得FOutSize和FTmpSize只在create時用了一次
for i := FMin to FMax do
begin
for j := 0 to FLength - 1 do
begin
FSub[iTmpSize] := i
//為哪個數賦值,假設這里是為第三個數賦值
end;

FTmpSize := iTmpSize + 1
//那么下一次就輪到為第四個數賦值了
iSum := 0;

if FTmpSize >= FLength then
begin
FStrSum:='';
for k := 0 to FLength - 1 do
begin
iSum := iSum + FSub[k];
FStrSum := FStrSum + IntToStr(Fsub[k]) + ' ';
end;

if iSum = FResult then
begin
FstrList.Add(FStrSum);
Synchronize(updatememo);
end;
end
else
begin
// OutSize:=iOutSize+1;
SumSum(FTmpSize);
end;
end;
end;

procedure Tf_SumEx.btnRunThread1Click(Sender: TObject);
begin
ThreadOne:=TSumThread.create(StrToInt(edtSize.Text),
StrToInt(edtMinValue.Text),
StrToInt(edtMaxValue.Text),
StrToInt(edtResult.Text),
f_SumEx.Memo1);
end;

procedure TSumThread.UpdateMemo;
begin
FMemo.Lines.Add(FStrSum);
end;

procedure Tf_SumEx.btnRunThread2Click(Sender: TObject);
begin
TSumThread.create(StrToInt(edtSize.Text),
StrToInt(edtMinValue.Text),
StrToInt(edtMaxValue.Text),
StrToInt(edtResult.Text),
f_SumEx.Memo2);
end;

procedure Tf_SumEx.btnStopThread1Click(Sender: TObject);
begin
if ThreadOne<>nil then
if btnStopThread1.Tag=0 then
begin
btnStopThread1.Tag:=1;
ThreadOne.Suspend;
end
else
begin
btnStopThread1.Tag:=0;
ThreadOne.Resume;
end;
end;

end.
 
TO:BrainYang
如果不初始化数组a,就的时候再求值可以吗?
 
来自:阿九, 时间:2006-1-18 10:20:28, ID:3332645 | 编辑
TO:BrainYang
如果不初始化数组a,就的时候再求值可以吗?

已解
 
你說用的時候再求值?只用一個變量?我覺得不大可能。
不知道k有多少個啊。

第一個demo中用了一個二維數組a,一個一維數組asub。完全是多余的。愚蠢的做法。
第二個demo線程方式中只用一個一維數組FSub
FSub就沒有初始化數組,不過也差不多是全初始化為零,只是重設數組長度。
數組FSub的用途:
如時有3個數,那么SetLength(FSub,3)
FSub[0]放第一個數
FSub[1]放第二個數
FSub[2]放第三個數,只是這個作用。

如時有4個數,那么SetLength(FSub,4)
FSub[0]放第一個數
FSub[1]放第二個數
FSub[2]放第三個數
FSub[3]放第四個數
建議用第二個。
 
后退
顶部