Az alábbi letöltési lehetőségek közül választhatsz: (
segítség)
Típus: text/plain
Tartalmaz szöveget
Karakterkódolás: us-ascii
Méret: 3 KB
#include <stdio.h>
#define MaxDepth 10
struct s15 {
char Sq[16];
char Empty;
void Init (void) {
for (int I = 0; I < 16; I++)
Sq[I] = (I + 1) % 16;
Empty = 15;
}
inline void MoveEmpty (int D) {
Sq[Empty] = Sq[Empty + D];
Sq[Empty + D] = 0;
Empty += D;
}
void Print (void) {
for (int I = 0; I < 16; I++)
printf("%d ", Sq[I]);
printf(": %d\n", Empty);
}
} Step[MaxDepth], Sol;
int Depth = 0;
char Moves[MaxDepth + 1] = {0};
bool operator == (const s15 &, const s15 &);
bool Read (const char *, s15 &);
bool Write (const char *, const char *);
bool Solvable (const s15 &);
bool Backtrack (void);
int main (int AN, char * Args []) {
if (AN < 3)
return 1;
if (!Read(Args[1], Step[0]))
return 1;
Sol.Init();
if (Backtrack())
Write(Args[2], Moves);
else
Write(Args[2], "Nincs megoldas.");
return 0;
}
bool operator == (const s15 & A, const s15 & B) {
for (int I = 0; I < 16; I++)
if (A.Sq[I] != B.Sq[I])
return false;
return true;
}
bool Read (const char * FN, s15 & In) {
FILE * F = fopen(FN, "rt");
int B;
if (F == NULL)
return false;
for (int I = 0; I < 16; I++) {
fscanf(F, "%d ", &B);
In.Sq[I] = B;
if (B == 0)
In.Empty = I;
}
fclose(F);
return true;
}
bool Write (const char * FN, const char * Out) {
FILE * F = fopen(FN, "wt");
if (F == NULL)
return false;
fprintf(F, "%s\n", Out);
fclose(F);
return true;
}
bool Solvable (const s15 & S) {
int I, J, X = 0;
for (I = 0; I < 16; I++)
for (J = I + 1; J < 16; J++)
if (S.Sq[I] > S.Sq[J])
X++;
return (X + (3 - S.Empty % 4) + (3 - S.Empty / 4)) % 2 == 0;
}
bool Backtrack (void) {
static char Dir[4] = {1, -4, -1, 4};
static char Let[4] = {'J', 'F', 'B', 'L'};
static char RLet[4] = {'B', 'L', 'J', 'F'};
if (Step[Depth] == Sol) {
Moves[Depth] = 0;
return true;
}
if (Depth + 1 == MaxDepth)
return false;
int I, J;
char PrevLet = Depth > 0 ? Moves[Depth - 1] : ' ';
Step[Depth + 1] = Step[Depth];
Depth++;
for (I = 0; I < 4; I++) {
if (RLet[I] == PrevLet)
continue;
if (Step[Depth].Empty + Dir[I] < 0 || Step[Depth].Empty + Dir[I] >= 16)
continue;
Step[Depth].MoveEmpty(Dir[I]);
Moves[Depth - 1] = Let[I];
for (J = 0; J < Depth; J++)
if (Step[J] == Step[Depth])
break;
if (J == Depth && Backtrack())
return true;
Step[Depth].MoveEmpty(-Dir[I]);
}
Depth--;
return false;
}