Const SOUBOR_VSTUP = 'mrizka.txt';
SOUBOR_VYSTUP = 'vystup.txt';
MaxN = 16;
Type TMrizka = Array [0 .. MaxN+1, 0 .. MaxN+1] Of Boolean;
TVelikost = 1 .. MaxN;
Var M : TMrizka;
N : TVelikost; { velikost mrizky }
Max : Integer;
I : Integer;
S : String;
{ Prevede znak z fiktivniho retezce na pozivi v mrizce,
Pozice je pozice v retezci, pocitano od nuly.
(X,Y) jsou souradnice v poli TMrizka }
Procedure Convert(Pozice : Integer; Kvadrant : Char;
Var X, Y : Integer);
Var kx, ky : Integer; { pozice v kvadrantu }
M : Integer; {N/2}
Begin
M := N Div 2;
kx := Pozice Mod M;
ky := Pozice Div M;
Case Kvadrant Of
'A' : Begin
X := kx;
Y := ky;
End;
'B' : Begin
Y := kx;
X := -ky - 1;
End;
'C' : Begin
X := -kx - 1;
Y := -ky - 1;
End;
'D' : Begin
X := ky;
Y := -kx - 1;
End;
End;
X := X + M + 1;
Y := Y + M + 1;
End;
Function DiraOk(X, Y : Integer) : Boolean;
Begin
DiraOk := Not (M[X+1, Y] Or M[X-1, Y] Or M[X, Y-1] Or M[X, Y+1])
End;
{ nacte mrizku ze souboru }
Procedure NactiMrizku;
Var I, J, B : Integer;
F : Text;
Begin
{ otevreni souboru pro cteni }
Assign(F, SOUBOR_VSTUP);
Reset(F);
{ nacteni dat }
Readln(F, N);
For J := 1 To N Do
Begin
For I := 1 To N Do
Begin
Read(F, B);
M[I, J] := B > 0;
End;
End;
{Vynulovani okraju}
For I := 0 To N+1 Do
Begin
M[0, I] := False;
M[I, 0] := False;
M[I, N+1] := False;
M[N+1, I] := False;
End;
{ uzavreni souboru }
Close(F);
End;
Procedure NastavRetezec;
Var I, X, Y : Integer;
C : Char;
Begin
S := '';
For I := 1 To N*N Div 4 Do
Begin
S := S + 'X';
{ Otestujeme, zda je na teto pozici dira }
For C := 'A' To 'D' Do
Begin
Convert(I-1, C, X, Y);
If M[X, Y] Then
Begin
S[I] := C;
Break;
End;
End;
End;
End;
Function R(D : Integer) : Longint;
Var Sum : Longint;
X, Y : Integer;
C : Char;
Begin
If D = Max Then
R := 1
Else If S[D+1] <> 'X' Then
R := R(D+1)
Else
Begin
Sum := 0;
{ Cyklus pres vsechny kamarady }
For C := 'A' To 'D' Do
Begin
Convert(D, C, X, Y);
{ Vyrobime diru, a zavolame R }
If DiraOk(X, Y) Then
Begin
M[X, Y] := True;
S[D+1] := C;
Sum := Sum + R(D+1);
M[X, Y] := False;
End;
End;
S[D+1] := 'X';
R := Sum;
End;
End;
Procedure ZapisVysledek(V : Longint);
Var F : Text;
Begin
{ otevreni souboru pro zapis }
Assign(F, SOUBOR_VYSTUP);
Rewrite(F);
Writeln(F, V);
Close(F);
End;
Begin
NactiMrizku;
Max := N*N Div 4;
NastavRetezec;
Writeln(R(0));
ZapisVysledek(R(0));
End.