关于一个循环历遍的问题。(50)

  • 主题发起人 ppqingyu
  • 开始时间
P

ppqingyu

Unregistered / Unconfirmed
GUEST, unregistred user!
在一个20*20的个小格子的平面,有4个球,每个球的直径是两个小格子的大小,我想历遍整个平面,看小球在平面上有几种排列位置。有一个要求,小球的位置不能重叠,例如,球A占了1、2、11、12这四个格子的时候,其他的球就不能再占用其中的格子了。这个循环怎么写才更有效率?因为当中需要判断是否重叠了。
 
W

why_119

Unregistered / Unconfirmed
GUEST, unregistred user!
听着都迷糊.我.不会
 
F

fwd

Unregistered / Unconfirmed
GUEST, unregistred user!
不是太难吧,结果应该是不少!400*399*398*397/(4*3*2*1)
 
Y

yixueying2003

Unregistered / Unconfirmed
GUEST, unregistred user!
有意思,好象也有点儿麻烦,帮你顶一下
 
Y

yixueying2003

Unregistered / Unconfirmed
GUEST, unregistred user!
是(19*19)*(19*17+17*2)*(19*17+15*2)*(19*17+13*2)这么多种放法,但遍历还没想出来怎么写
 
Z

znxia

Unregistered / Unconfirmed
GUEST, unregistred user!
通过递归循环计算,计算2个球不重叠的放置方法需要1秒,3个球不重叠的放置方法需要秒44秒,4个球,时间太长,无结果,终止了。procedure TForm1.Button1Click(Sender: TObject);var Data: array[0..19, 0..19] of smallint
procedure ClearDept(Dept: Smallint)
var row, col: Integer
begin for Row := 0 to 19 do for col := 0 to 19 do if Data[Row, Col] >= Dept then Data[Row, Col] := 0
end
function GetTimes(Dept: smallint): Integer
var row, col: Integer
begin Result := 0
for Row := 0 to 18 do for col := 0 to 18 do begin if (Data[Row, Col] or Data[Row, Col + 1] or Data[Row + 1, Col] or Data[Row + 1, Col + 1]) = 0 then begin Data[Row, Col] := Dept
Data[Row, Col + 1] := Dept
Data[Row + 1, Col] := Dept
Data[Row + 1, Col + 1] := Dept
if Dept = 3 then //测试时用3个球来计算的 Inc(Result) else Result := Result + GetTimes(Dept + 1)
//根据当前球的放置方法,检索剩余的球可以放置的方法数 ClearDept(Dept)
end
end
end;begin Caption := Datetimetostr(Now)
fillchar(Data, sizeof(Data), 0)
Edit1.text := IntToStr(GetTimes(1))
Button1.Caption := Datetimetostr(Now);end;
 
Z

znxia

Unregistered / Unconfirmed
GUEST, unregistred user!
yixueying2003,如果第一个球放置的位置是B1,C1,B2,C2(按Excell单元格的位置来说),则第二个球的放置方法还有 (19*17+17*2) 那么多吗?
 
Y

yixueying2003

Unregistered / Unconfirmed
GUEST, unregistred user!
我说的情况应该是四个球是不同的球,如颜色什么的都是一样的应该就没这么多种放法了吧,我自己的想法,还没通过证实呢,正在试
 
Z

znxia

Unregistered / Unconfirmed
GUEST, unregistred user!
这个题目的确有点意思。我也是考虑的是四个球是不同的球。如果第一个球放置在A1:B2区间内,则第二个球的可放置的位置数量就是 (19*17+17*2),但如果放置在 B1:C2区间内,则二个球的可放置的位置数量就没那么多了。
 
Y

yixueying2003

Unregistered / Unconfirmed
GUEST, unregistred user!
同志们看看哪儿还不对呢var a1,a2,b1,b2,c1,c2,d1,d2:Integer
num:DWORD;begin num:=0
for a1:=1 to 19 do begin for a2:= 1 to 19 do begin For b1:=1 to 19 do begin for b2:=1 to 19 do begin if a1=b1 then begin if a2=1 then begin if (b2=1) or (b2=2) then Continue
end
if a2=19 then begin if (b2=18) or (b2=9) then Continue
end
if Abs(b2-a2)<=1 then Continue
end
for c1:=1 to 19 do begin for c2:=1 to 19 do begin if (a1=c1) then begin if a2=1 then begin if (c2=1) or (c2=2) then Continue
end
if a2=19 then begin if (c2=18) or (c2=9) then Continue
end
if Abs(c2-a2)<=1 then Continue
end
if (c1=b1) then begin if b2=1 then begin if (c2=1) or (c2=2) then Continue
end
if b2=19 then begin if (c2=18) or (c2=9) then Continue
end
if Abs(c2-b2)<=1 then Continue
end
for d1:=1 to 19 do begin for d2:= 1 to 19 do begin if (a1=d1) then begin if a2=1 then begin if (d2=1) or (d2=2) then Continue
end
if a2=19 then begin if (d2=18) or (d2=9) then Continue
end
if Abs(d2-a2)<=1 then Continue
end
if (d1=b1) then begin if b2=1 then begin if (d2=1) or (d2=2) then Continue
end
if b2=19 then begin if (d2=18) or (d2=9) then Continue
end
if Abs(d2-b2)<=1 then Continue
end
if (d1=c1) then begin if c2=1 then begin if (d2=1) or (d2=2) then Continue
end
if c2=19 then begin if (d2=18) or (d2=9) then Continue
end
if Abs(d2-c2)<=1 then Continue
end
if Abs(d1-a1)=1 then begin if Abs(d2-a2)<=1 then Continue
end
if Abs(d1-b1)=1 then begin if Abs(d2-b2)<=1 then Continue
end
if Abs(d1-c1)=1 then begin if Abs(d2-c2)<=1 then Continue
end
// mmo1.Lines.Add(' a1:'+inttostr(a1)+' a2:'+inttostr(a2)+' b1:'+inttostr(b1)+' b2:'+inttostr(b2)+' c1:'+inttostr(c1)+' c2:'+inttostr(c2)+' d1:'+inttostr(d1)+' d2:'+inttostr(d2))
//AddLog(' a1:'+inttostr(a1)+' a2:'+inttostr(a2)+' b1:'+inttostr(b1)+' b2:'+inttostr(b2)+' c1:'+inttostr(c1)+' c2:'+inttostr(c2)+' d1:'+inttostr(d1)+' d2:'+inttostr(d2))
Inc(num)
end
end
end
end
end
end
end
end
edt1.Text:=IntToStr(num);end;
 
Y

yixueying2003

Unregistered / Unconfirmed
GUEST, unregistred user!
[:(]粘错了procedure TForm1.btn1Click(Sender: TObject);var a1,a2,b1,b2,c1,c2,d1,d2:Integer
num:DWORD;begin num:=0
for a1:=1 to 19 do begin for a2:= 1 to 19 do begin For b1:=1 to 19 do begin for b2:=1 to 19 do begin if a1=b1 then begin if a2=1 then begin if (b2=1) or (b2=2) then Continue
end
if a2=19 then begin if (b2=18) or (b2=19) then Continue
end
if Abs(b2-a2)<=1 then Continue
end
for c1:=1 to 19 do begin for c2:=1 to 19 do begin if (a1=c1) then begin if a2=1 then begin if (c2=1) or (c2=2) then Continue
end
if a2=19 then begin if (c2=18) or (c2=19) then Continue
end
if Abs(c2-a2)<=1 then Continue
end
if (c1=b1) then begin if b2=1 then begin if (c2=1) or (c2=2) then Continue
end
if b2=19 then begin if (c2=18) or (c2=19) then Continue
end
if Abs(c2-b2)<=1 then Continue
end
for d1:=1 to 19 do begin for d2:= 1 to 19 do begin if (a1=d1) then begin if a2=1 then begin if (d2=1) or (d2=2) then Continue
end
if a2=19 then begin if (d2=18) or (d2=19) then Continue
end
if Abs(d2-a2)<=1 then Continue
end
if (d1=b1) then begin if b2=1 then begin if (d2=1) or (d2=2) then Continue
end
if b2=19 then begin if (d2=18) or (d2=19) then Continue
end
if Abs(d2-b2)<=1 then Continue
end
if (d1=c1) then begin if c2=1 then begin if (d2=1) or (d2=2) then Continue
end
if c2=19 then begin if (d2=18) or (d2=19) then Continue
end
if Abs(d2-c2)<=1 then Continue
end
if Abs(d1-a1)=1 then begin if Abs(d2-a2)<=1 then Continue
end
if Abs(d1-b1)=1 then begin if Abs(d2-b2)<=1 then Continue
end
if Abs(d1-c1)=1 then begin if Abs(d2-c2)<=1 then Continue
end
// mmo1.Lines.Add(' a1:'+inttostr(a1)+' a2:'+inttostr(a2)+' b1:'+inttostr(b1)+' b2:'+inttostr(b2)+' c1:'+inttostr(c1)+' c2:'+inttostr(c2)+' d1:'+inttostr(d1)+' d2:'+inttostr(d2))
//AddLog(' a1:'+inttostr(a1)+' a2:'+inttostr(a2)+' b1:'+inttostr(b1)+' b2:'+inttostr(b2)+' c1:'+inttostr(c1)+' c2:'+inttostr(c2)+' d1:'+inttostr(d1)+' d2:'+inttostr(d2))
Inc(num)
end
end
end
end
end
end
end
end
edt1.Text:=IntToStr(num);end;
 
Z

znxia

Unregistered / Unconfirmed
GUEST, unregistred user!
测试你的算法,大概需要130秒左右,结果是2558472516,按理说应该可以整除24,但2558472516/24=106603021.5,可能还有哪个地方没考虑周全。我修改了一下算法,速度没你的快,需要160秒,结果是1847728728,当然,标准答案出来之前,我也不敢说自己的结果是正确的。procedure TForm1.Button1Click(Sender: TObject);var Data: array[0..19, 0..19] of smallint
function GetTimes(Dept: smallint): Integer
var row, col: Integer
begin Result := 0
for Row := 0 to 18 do for col := 0 to 18 do begin if (Data[Row, Col] or Data[Row, Col + 1] or Data[Row + 1, Col] or Data[Row + 1, Col + 1]) = 0 then begin Data[Row, Col] := Dept
Data[Row, Col + 1] := Dept
Data[Row + 1, Col] := Dept
Data[Row + 1, Col + 1] := Dept
if Dept = 4 then Inc(Result) else Result := Result + GetTimes(Dept + 1)
Data[Row, Col] := 0
Data[Row, Col + 1] := 0
Data[Row + 1, Col] := 0
Data[Row + 1, Col + 1] := 0
end
end
end;begin Caption := Datetimetostr(Now)
fillchar(Data, sizeof(Data), 0)
Edt1.text := IntToStr(GetTimes(1))
Button1.Caption := Datetimetostr(Now);end;
 
Z

zaorv

Unregistered / Unconfirmed
GUEST, unregistred user!
用二维坐标方法,
 
顶部