на поле размером N*M (1<=N<=10,1<=M<=15) расставляются 4 корабля: однопалубный, 2-палубный,3-палубный и 4-палубный.Корабли могут располагатся вертикально и горизонтально, не соприкасаясь друг с другом углами и границами. Требуется определить количество вариантов расположения кораблей на игровом поле.
var f: array[1..n,1..m]of boolean; i,j: integer; p: LongInt; b: boolean;
procedure Show; var i,j: integer; begin for i:=1 to n do begin for j:=1 to m do if f[i,j] then Write('X') else Write('-'); WriteLn end; readLn; end;
procedure Put(l: integer); var i,j,x,y: integer; begin if l=0 then begin Inc(p); //Show // uncomment this line to see the board end else begin for x:=2 to n-l do for y:=2 to m-l do begin b:=false; for i:=-1 to l do for j:=-1 to 1 do b:=b or f[x+i,y+j]; if not b then begin for i:=0 to l-1 do f[x+i,y]:=true; Put(l-1); for i:=0 to l-1 do f[x+i,y]:=false end end; if l>1 then for x:=2 to n-l do for y:=2 to m-l do begin b:=false; for i:=-1 to 1 do for j:=-1 to l do b:=b or f[x+i,y+j]; if not b then begin for i:=0 to l-1 do f[x,y+i]:=true; Put(l-1); for i:=0 to l-1 do f[x,y+i]:=false end end end end;
begin for i:=1 to n do for j:=1 to m do f[i,j]:=false; p:=0; Count(l); WriteLn(p) end.
Способ второй (через массив координат кораблей)
const n= 10; m= 15; l0= 4;
var Ship: array [1..l0] of record x1,y1,x2,y2: integer end; p: LongInt;
procedure Show; var i,j,k: integer; b: boolean; begin for i:=1 to n do begin for j:=1 to m do begin b:=false; for k:=1 to l0 do with Ship[k] do b:=b or (x1<=i)and(i<=x2)and(y1<=j)and(j<=y2); if b then Write('X') else Write('-') end; WriteLn end; ReadLn end;
procedure Put(l: integer); var x,y,i,j: integer; b: boolean; begin if l=0 then begin Inc(p); //Show // uncomment this line to see the board end else for x:=2 to n-l do for y:=2 to m-l do begin b:=false; for i:=l0 downto l+1 do with Ship[i] do b:=b or ( (x1-1<=x)and(x<=x2+1)or (x1-1<=x+l-1)and(x+l-1<=x2+1)or (x<x1-1)and(x2+1<x) ) and(y1-1<=y)and(y<=y2+1); if not b then with Ship[l] do begin x1:=x; x2:=x+l-1; y1:=y; y2:=y; Put(l-1) end end; if l>1 then for x:=2 to n-l do for y:=2 to m-l do begin b:=false; for i:=l0 downto l+1 do with Ship[i] do b:=b or ( (y1-1<=y)and(y<=y2+1)or (y1-1<=y+l-1)and(y+l-1<=y2+1)or (y<y1-1)and(y2+1<y) ) and(x1-1<=x)and(x<=x2+1); if not b then with Ship[l] do begin x1:=x; x2:=x; y1:=y; y2:=y+l-1; Put(l-1) end end; end;
begin p:=0; Put(l0); WriteLn(p) end.
В обеих программах добавлена ненужная по большому счету процедура вывода текущей конфигурации - ее вызов закомментирован.
--------------------
я - ветер, я северный холодный ветер я час расставанья, я год возвращенья домой