Вы находитесь на странице: 1из 24

Sudoku

#define DIM 9
#define BLANK 0
#define SPACE " "
#define LINE "|"
#define NEW_ROW "-------------------------------------"
#define GRID_FULL std::make_pair(9, 9)

// Prints the Soduko grid


void print_grid(int grid[DIM][DIM])
{
for (int i = 0; i < DIM; i++)
{
cout << SPACE << SPACE << SPACE << SPACE << endl;
cout << NEW_ROW << endl;
for (int j = 0; j < DIM; j++)
{
cout << SPACE;
if (BLANK == grid[i][j])
{
cout << SPACE;
}
else
{
cout << grid[i][j];
}
cout << SPACE;
cout << LINE;
}
}
cout << endl << NEW_ROW << endl << endl;;
}

// Returns a boolean which indicates whether any assigned entry


// in the specified row matches the given number.
bool used_in_row(int grid[DIM][DIM], int row, int num)
{
for (int col = 0; col < DIM; col++)
if (grid[row][col] == num)
{
return true;
}
return false;
}

// Returns a boolean which indicates whether any assigned entry


// in the specified column matches the given number.
bool used_in_col(int grid[DIM][DIM], int col, int num)
{
for (int row = 0; row < DIM; row++)
if (grid[row][col] == num)
{
return true;
}
return false;
}

// Returns a boolean which indicates whether any assigned entry


// within the specified 3x3 box matches the given number.
bool used_in_box(int grid[DIM][DIM], int box_start_rpw, int box_start_col, int num)
{
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid[row + box_start_rpw][col + box_start_col] == num)
{
return true;
}
return false;
}

// Returns a boolean which indicates whether it will be legal to assign


// num to the given row,col location.
bool is_safe(int grid[DIM][DIM], int row, int col, int num)
{
// Check if 'num' is not already placed in current row,
// current column and current 3x3 box
return !used_in_row(grid, row, num) &&
!used_in_col(grid, col, num) &&
!used_in_box(grid, row - row % 3, col - col % 3, num);
}

// Searches the grid to find an entry that is still unassigned. If


// found, the reference parameters row, col will be set the location
// that is unassigned, and true is returned. If no unassigned entries
// remain, false is returned.
std::pair<int, int> get_unassigned_location(int grid[DIM][DIM])
{
for (int row = 0; row < DIM; row++)
for (int col = 0; col < DIM; col++)
if (grid[row][col] == BLANK)
{
return std::make_pair(row, col);
}
return GRID_FULL;
}
// Takes a partially filled-in grid and attempts to assign values to
// all unassigned locations in such a way to meet the requirements
// for Sudoku solution (non-duplication across rows, columns, and boxes)
bool solve_soduko(int grid[DIM][DIM])
{
// If the Soduko grid has been filled, we are done
if (GRID_FULL == get_unassigned_location(grid))
{
return true;
}

// Get an unassigned Soduko grid location


std::pair<int, int> row_and_col = get_unassigned_location(grid);
int row = row_and_col.first;
int col = row_and_col.second;

// Consider digits 1 to 9
for (int num = 1; num <= 9; num++)
{
// If placing the current number in the current
// unassigned location is valid, go ahead
if (is_safe(grid, row, col, num))
{
// Make tentative assignment
grid[row][col] = num;

// Do the same thing again recursively. If we go


// through all of the recursions, and in the end
// return true, then all of our number placements
// on the Soduko grid are valid and we have fully
// solved it
if (solve_soduko(grid))
{
return true;
}

// As we were not able to validly go through all


// of the recursions, we must have an invalid number
// placement somewhere. Lets go back and try a
// different number for this particular unassigned location
grid[row][col] = BLANK;
}
}

// If we have gone through all possible numbers for the current unassigned
// location, then we probably assigned a bad number early. Lets backtrack
// and try a different number for the previous unassigned locations.
return false;
}
int main()
{
cout << "********************************\n\n\tSudoku
Solver\n\n********************************" << endl << endl;

int grid[DIM][DIM] = { { 0, 9, 0, 0, 0, 0, 8, 5, 3 },
{ 0, 0, 0, 8, 0, 0, 0, 0, 4 },
{ 0, 0, 8, 2, 0, 3, 0, 6, 9 },
{ 5, 7, 4, 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 0, 6, 3, 7 },
{ 9, 4, 0, 1, 0, 8, 5, 0, 0 },
{ 7, 0, 0, 0, 0, 6, 0, 0, 0 },
{ 6, 8, 2, 0, 0, 0, 0, 9, 0 } };

print_grid(grid);

if (true == solve_soduko(grid))
{
print_grid(grid);
}
else
{
cout << "No solution exists for the given Soduko" << endl << endl;
}

return 0;
}
https://medium.com/@george.seif94/solving-sudoku-using-a-simple-search-algorithm-3ac44857fee8

https://github.com/GeorgeSeif/Sudoku-Solver

#include <iostream>
#include <algorithm>
#include <vector>
#include <array>

using std::cout;
using std::endl;
#define DIM 9
#define BLANK 0
#define SPACE " "
#define LINE "|"
#define NEW_ROW "-------------------------------------"
#define GRID_FULL std::make_pair(9, 9)

// Prints the Soduko grid


void print_grid(int grid[DIM][DIM])
{
for (int i = 0; i < DIM; i++)
{
cout << SPACE << SPACE << SPACE << SPACE << endl;
cout << NEW_ROW << endl;
for (int j = 0; j < DIM; j++)
{
cout << SPACE;
if (BLANK == grid[i][j])
{
cout << SPACE;
}
else
{
cout << grid[i][j];
}
cout << SPACE;
cout << LINE;
}
}
cout << endl << NEW_ROW << endl << endl;;
}

// Returns a boolean which indicates whether any assigned entry


// in the specified row matches the given number.
bool used_in_row(int grid[DIM][DIM], int row, int num)
{
for (int col = 0; col < DIM; col++)
if (grid[row][col] == num)
{
return true;
}
return false;
}

// Returns a boolean which indicates whether any assigned entry


// in the specified column matches the given number.
bool used_in_col(int grid[DIM][DIM], int col, int num)
{
for (int row = 0; row < DIM; row++)
if (grid[row][col] == num)
{
return true;
}
return false;
}

// Returns a boolean which indicates whether any assigned entry


// within the specified 3x3 box matches the given number.
bool used_in_box(int grid[DIM][DIM], int box_start_rpw, int box_start_col, int num)
{
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid[row + box_start_rpw][col + box_start_col] == num)
{
return true;
}
return false;
}

// Returns a boolean which indicates whether it will be legal to assign


// num to the given row,col location.
bool is_safe(int grid[DIM][DIM], int row, int col, int num)
{
// Check if 'num' is not already placed in current row,
// current column and current 3x3 box
return !used_in_row(grid, row, num) &&
!used_in_col(grid, col, num) &&
!used_in_box(grid, row - row % 3, col - col % 3, num);
}

// Searches the grid to find an entry that is still unassigned. If


// found, the reference parameters row, col will be set the location
// that is unassigned, and true is returned. If no unassigned entries
// remain, false is returned.
std::pair<int, int> get_unassigned_location(int grid[DIM][DIM])
{
for (int row = 0; row < DIM; row++)
for (int col = 0; col < DIM; col++)
if (grid[row][col] == BLANK)
{
return std::make_pair(row, col);
}
return GRID_FULL;
}

// Takes a partially filled-in grid and attempts to assign values to


// all unassigned locations in such a way to meet the requirements
// for Sudoku solution (non-duplication across rows, columns, and boxes)
bool solve_soduko(int grid[DIM][DIM])
{
// If the Soduko grid has been filled, we are done
if (GRID_FULL == get_unassigned_location(grid))
{
return true;
}

// Get an unassigned Soduko grid location


std::pair<int, int> row_and_col = get_unassigned_location(grid);
int row = row_and_col.first;
int col = row_and_col.second;

// Consider digits 1 to 9
for (int num = 1; num <= 9; num++)
{
// If placing the current number in the current
// unassigned location is valid, go ahead
if (is_safe(grid, row, col, num))
{
// Make tentative assignment
grid[row][col] = num;

// Do the same thing again recursively. If we go


// through all of the recursions, and in the end
// return true, then all of our number placements
// on the Soduko grid are valid and we have fully
// solved it
if (solve_soduko(grid))
{
return true;
}

// As we were not able to validly go through all


// of the recursions, we must have an invalid number
// placement somewhere. Lets go back and try a
// different number for this particular unassigned location
grid[row][col] = BLANK;
}
}

// If we have gone through all possible numbers for the current unassigned
// location, then we probably assigned a bad number early. Lets backtrack
// and try a different number for the previous unassigned locations.
return false;
}

int main()
{
cout << "********************************\n\n\tSudoku
Solver\n\n********************************" << endl << endl;

int grid[DIM][DIM] = { { 0, 9, 0, 0, 0, 0, 8, 5, 3 },
{ 0, 0, 0, 8, 0, 0, 0, 0, 4 },
{ 0, 0, 8, 2, 0, 3, 0, 6, 9 },
{ 5, 7, 4, 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 0, 6, 3, 7 },
{ 9, 4, 0, 1, 0, 8, 5, 0, 0 },
{ 7, 0, 0, 0, 0, 6, 0, 0, 0 },
{ 6, 8, 2, 0, 0, 0, 0, 9, 0 } };

print_grid(grid);

if (true == solve_soduko(grid))
{
print_grid(grid);
}
else
{
cout << "No solution exists for the given Soduko" << endl << endl;
}

return 0;
}

C how to_program_6th
http://docerp.ro/exercitii-de-programare-in-c-c/

http://docerp.ro/all_titles/

#include<iostream>
//permutari
#include<fstream>
#include<bitset>
using namespace std;
int st[9],n;
bitset <9> d;
ofstream g("permutari.out");
void afiseaza(int n)
{
int i;
for(i=1;i<=n;i++)
g<<st[i]<<" ";
g<<'\n';
}
void bktr(int p)
{
int pval;
for(pval=1;pval<=n;pval++)
if(d[pval]==0) {
d[pval]=1;
st[p]=pval;
if(p==n)
afiseaza(p);
else bktr(p+1);
d[pval]=0;
}
}
int main ()
{
ifstream f("permutari.in");
f>>n;
f.close();
bktr(1);
g.close();
return 0;
}

subm
#include<iostream>
#include<fstream>
using namespace std;
#define NMAX 17
ofstream g("submultimi.out");
int st[NMAX],n;
inline void afisare(int n)
{
int i;
for(i=1;i<=n;i++)
g<<st[i]<<" ";
g<<'\n';
}
inline void bktr(int p)
{
int pval;
for(pval=st[p-1]+1;pval<=n;pval++) {
st[p]=pval;
afisare(p);
if(p<n)
bktr(p+1);
}
}
int main ()
{
ifstream f("submultimi.in");
f>>n;
f.close();
bktr(1);
g.close();
return 0;
}

Combin

#include<iostream
>
#include<fstream>
using namespace std;
#define NMAX 19
ofstream g("combinari.out");
int st[NMAX],n,k;
inline void afisare()
{
int i;
for(i=1;i<=k;i++)
g<<st[i]<<" ";
g<<'\n';
}
inline void bktr(int p)
{
int pval;
for(pval=st[p-1]+1;pval<=n-k+p;pval++) {
st[p]=pval;
if(p==k)
afisare();
else bktr(p+1);
}
}
int main ()
{
ifstream f("combinari.in");
f>>n>>k;
f.close();
bktr(1);
g.close();
return 0;
}
Scriet¸i un program C/C++ care cite¸ste din fi¸sierul standard de intrare (tastatura)
¸siruri de caractere de forma cuvˆant#tip, unde cuvˆant este un ¸sir oarecare de litere
iar tip poate fi una din literele S,P sau C, semnificat¸ia fiind subiect, predicat sau
complement. Aplicat¸ia va afi¸sa pe ecran toate propozit¸iile avˆand structura subiect
predicat complement ce pot fi formate cu ajutorul cuvintelor citite. Datele de intrare
se consider˘a a fi corecte.
Exemplu: dac˘a la intrare s-au introdus ¸sirurile: Ion#S Vasile#S alearga#P
repede#C scrie#P, atunci pe ecran se va afi¸sa: Ion scrie repede, Ion alearga
repede, Vasile scrie repede, Vasile alearga repede

Problema nu se rezolva cu permutari ci cu produs cartezian. Tu ai 3 multimi: S-multimea subiectelor, P-


multimea predicatelor si C-multimea complementelor. Tu trebuie sa generezi toate triplele de forma (a,b,c) cu a
apartine S, b apartine P si c apartine C.
Acum, cum faci back-ul? Ceva de genu:

back(nivel)
{
if(nivel==4) //am pus si subiect si predicat si complement
afisare();
else
{
for ( int i = 1; i <= M[ nivel ][ 0 ]; i++ ) //M[nivel][0] =
cardinalul multimii M[nivel], multime in care stochezi cele 3 multimi S,P,C; ai un
masiv 3-dimensional unde stochezi sirurile
{
st[ nivel ] = M[ nivel ][ i ];
back(nivel+1);
}
}
}

criet¸i un program C/C++ care cite¸ste din fi¸sierul standard de intrare (tastatura)
¸siruri de caractere de forma cuvˆant#tip, unde cuvˆant este un ¸sir oarecare de litere
iar tip poate fi una din literele S,P sau C, semnificat¸ia fiind subiect, predicat sau
complement. Aplicat¸ia va afi¸sa pe ecran toate propozit¸iile avˆand structura subiect
predicat complement ce pot fi formate cu ajutorul cuvintelor citite. Datele de intrare
se consider˘a a fi corecte.
Exemplu: dac˘a la intrare s-au introdus ¸sirurile: Ion#S Vasile#S alearga#P
repede#C scrie#P, atunci pe ecran se va afi¸sa: Ion scrie repede, Ion alearga
repede, Vasile scrie repede, Vasile alearga repede

#include<fstream>
using namespace std;

int n,ST[100],as,ev,k,y=0,l=0,z=0;

ifstream f("paranteze.in");
ofstream g("paranteze.out");

void init()
{
ST[k]=-1;

void succ()
{

if(ST[k]<2)
{
ST[k]++;
as=1;
}
else as=0;

void valid()
{
ev=1;
for(int i=1;i<=k;i++)
{
if(ST[i]==0)
{
y++;
for(int j=i+1;j<=k;j++)
{
if(ST[j]==1)
l++;}}
else z++;

}
if(l==0)
ev=0;
if(z!=y!=n/2)
ev=0;
}

void tipar()
{
for(int i=1;i<=k;i++)
g<<ST[i]<<" ";
g<<endl;
}

int sol()
{

return (k==n);
}

void back()
{
k=1;
init();
while(k)
{
do{
succ();
if(as)
valid();

}
while(as && !ev);
if(as) if(sol())
tipar();
else{
k++;
init();
}
else k--;
}

int main()
{
f>>n;
back();
f.close();
g.close();
return 0;
}

https://www.geeksforgeeks.org/c-programs-gq/cc-backtracking-programs-gq/

Sudoku | Backtracking-7
https://www.geeksforgeeks.org/sudoku-
backtracking-7/
Given a partially filled 9×9 2D array ‘grid[9][9]’, the goal is to assign digits (from 1 to 9) to the empty
cells so that every row, column, and subgrid of size 3×3 contains exactly one instance of the digits from
1 to 9.

Recommended: Please solve it on “PRACTICE ” first, before


moving on to the solution.

Naive Algorithm
The Naive Algorithm is to generate all possible configurations of numbers from 1 to 9 to fill the empty
cells. Try every configuration one by one until the correct configuration is found.

Backtracking Algorithm
Like all other Backtracking problems, we can solve Sudoku by one by one assigning numbers to empty
cells. Before assigning a number, we check whether it is safe to assign. We basically check that the
same number is not present in the current row, current column and current 3X3 subgrid. After checking
for safety, we assign the number, and recursively check whether this assignment leads to a solution or
not. If the assignment doesn’t lead to a solution, then we try next number for the current empty cell.
And if none of the number (1 to 9) leads to a solution, we return false.

Find row, col of an unassigned cell


If there is none, return true
For digits from 1 to 9
a) If there is no conflict for digit at row, col
assign digit to row, col and recursively try fill in rest of grid
b) If recursion successful, return true
c) Else, remove digit and try another
If all digits have been tried and nothing worked, return false

Following are the implementation for Sudoku problem. It prints the completely filled grid as output.
filter_none

edit

play_arrow

brightness_4

// A Backtracking program in C++ to solve

// A Backtracking program in C++ to solve Sudoku problem


#include <stdio.h>

// UNASSIGNED is used for empty cells in sudoku grid


#define UNASSIGNED 0

// N is used for the size of Sudoku grid. Size will be NxN


#define N 9

// This function finds an entry in grid that is still unassigned


bool FindUnassignedLocation(int grid[N][N], int &row, int &col);

// Checks whether it will be legal to assign num to the given row, col
bool isSafe(int grid[N][N], int row, int col, int num);

/* Takes a partially filled-in grid and attempts to assign values to


all unassigned locations in such a way to meet the requirements
for Sudoku solution (non-duplication across rows, columns, and boxes) */
bool SolveSudoku(int grid[N][N])
{
int row, col;

// If there is no unassigned location, we are done


if (!FindUnassignedLocation(grid, row, col))
return true; // success!

// consider digits 1 to 9
for (int num = 1; num <= 9; num++)
{
// if looks promising
if (isSafe(grid, row, col, num))
{
// make tentative assignment
grid[row][col] = num;

// return, if success, yay!


if (SolveSudoku(grid))
return true;

// failure, unmake & try again


grid[row][col] = UNASSIGNED;
}
}
return false; // this triggers backtracking
}

/* Searches the grid to find an entry that is still unassigned. If


found, the reference parameters row, col will be set the location
that is unassigned, and true is returned. If no unassigned entries
remain, false is returned. */
bool FindUnassignedLocation(int grid[N][N], int &row, int &col)
{
for (row = 0; row < N; row++)
for (col = 0; col < N; col++)
if (grid[row][col] == UNASSIGNED)
return true;
return false;
}

/* Returns a boolean which indicates whether an assigned entry


in the specified row matches the given number. */
bool UsedInRow(int grid[N][N], int row, int num)
{
for (int col = 0; col < N; col++)
if (grid[row][col] == num)
return true;
return false;
}

/* Returns a boolean which indicates whether an assigned entry


in the specified column matches the given number. */
bool UsedInCol(int grid[N][N], int col, int num)
{
for (int row = 0; row < N; row++)
if (grid[row][col] == num)
return true;
return false;
}

/* Returns a boolean which indicates whether an assigned entry


within the specified 3x3 box matches the given number. */
bool UsedInBox(int grid[N][N], int boxStartRow, int boxStartCol, int num)
{
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid[row+boxStartRow][col+boxStartCol] == num)
return true;
return false;
}

/* Returns a boolean which indicates whether it will be legal to assign


num to the given row,col location. */
bool isSafe(int grid[N][N], int row, int col, int num)
{
/* Check if 'num' is not already placed in current row,
current column and current 3x3 box */
return !UsedInRow(grid, row, num) &&
!UsedInCol(grid, col, num) &&
!UsedInBox(grid, row - row%3 , col - col%3, num)&&
grid[row][col]==UNASSIGNED;
}

/* A utility function to print grid */


void printGrid(int grid[N][N])
{
for (int row = 0; row < N; row++)
{
for (int col = 0; col < N; col++)
printf("%2d", grid[row][col]);
printf("\n");
}
}

/* Driver Program to test above functions */


int main()
{
// 0 means unassigned cells
int grid[N][N] = {{3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0},
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0}};
if (SolveSudoku(grid) == true)
printGrid(grid);
else
printf("No solution exists");

return 0;
}

Output:

3 1 6 5 7 8 4 9 2
5 2 9 1 3 4 7 6 8
4 8 7 6 2 9 5 3 1
2 6 3 4 1 5 9 8 7
9 7 4 8 6 3 1 2 5
8 5 1 7 9 2 6 4 3
1 3 8 9 4 7 2 5 6
6 9 2 3 5 1 8 7 4
7 4 5 2 8 6 3 1 9

Se dă un labirint reprezentat sub forma unei matrici cu n linii şi m coloane, conţinând doar valori 0 şi 1. O
succesiune de 1 reprezintă un drum iar o (zero) reprezintă un zid. Dintr-un punct iniţial, a cărui coordonate se
citesc, porneşte o persoană. Să se afişeze toate posibilităţile ca acea persoană să ajunga in pozitia finala, ştiind
că deplasarea se poate face doar prin valori 1 ale matricei, iar salturile se pot face în stânga, dreapta, jos şi sus.

 Un fisier de intrare, sa-i zicem „labirint.in” in care scriem urmatoarele valori:


58
11
36
01000010

158
211
336
401000010
501111110
601000010
711111110
800001000

Cu urmatoarea semnificatie:

 5 8 – dimensiunile matricei (incepem numaratoarea de la 0, dupa cum v-am obisnuit)


 1 1 – coordonatele de pornire in matrice
 3 6 – coordonatele de sosire in matrice
 o succesiune de 1, reprezinta o cale libera

De asemenea, in problema mai mentioneaza si faptul ca deplasarea se face doar in 4 directii:

 Nord: (-1, 0)
 Est: (0, +1)
 Sud: (+1, 0)
 Vest: (0, -1)

Sa trecem la rezolvarea problemei, o sa explic fiecare functie in parte mai jos, si de asemenea o sa fac si
o mica animatie, dupa cum v-am obisnuit.

Functia bool isOK(int i, int j)

 Primeste ca si parametrii doua numere intregi i si j (sunt numere intregi deoarece pot sa primeasca si -1,
altfel le-am fi declarat „unsigned int”)
 Functia noastra verifica prima oara daca noile coordonate sunt in-afara matricei
 Mai apoi, accepta toate casutele ce sunt marcate cu 1 (drum disponibil, inca nevizitat) si de-asemenea
casuta de final (casuta de final va avea o valoare diferita de 1, in cazul in care se parcurge a doua oara –
a trebuit tratat separat acest caz)
 La final respingem toate casutele de 0 sau casutele diferite de 1 (casute disponibile, dar vizitate)

Functia void Rezolvare(int i, int j, int pas)

 Este o functie recursiva ce parcurge pe rand vecinii, iar mai apoi se intoarce de unde a plecat – similar
algoritmului lui Lee
 Aceasta functie verifica pe rand toti cei 4 vecini. In cazul in care casuta poate fi vizitata, aceasta functie
o viziteaza, iar cand se intoarce din recursivitate marcheaza casuta cu „0” (drum indisponibil)

https://tutoriale-pe.net/problema-labirintului-in-c-backtracking/

#include <fstream>
using namespace std;

ifstream fin("labirint.in");

const int N_MAX = 2005;


const int M_MAX = 2005;

int N, M;

unsigned int poz_init_X, poz_init_Y;


unsigned int poz_finala_X, poz_finala_Y;

unsigned int matrice[N_MAX][M_MAX];

const int directii = 4;


const int di[directii] = {-1, 0, 1, 0};
const int dj[directii] = {0, 1, 0, -1};

void Citire()
{
fin >> N >> M;
fin >> poz_init_X >> poz_init_Y;
fin >> poz_finala_X >> poz_finala_Y;

for(int i = 0; i < N; i++)


for(int j = 0; j < M; j++)
fin >> matrice[i][j];
}

bool isOK(int i, int j)


{
if(i > N || i < 1)
return false;
if(j > M || j < 1)
return false;

if(matrice[i][j] == 1 || (i == poz_finala_X && j == poz_finala_Y))


return true;

if(matrice[i][j] == 0 || matrice[i][j])
return false;

return true;
}

void afisare()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
cout << matrice[i][j] << " ";
cout << "\n";
}
cout << "\n\n";
}

void Rezolvare(int i, int j, int pas)


{
if(i == poz_finala_X && j == poz_finala_Y)
afisare();
else
{
for(int k = 0; k < directii; k++)
{
int i_vecin = i + di[k];
int j_vecin = j + dj[k];
if(isOK(i_vecin, j_vecin))
{
matrice[i_vecin][j_vecin] = pas;
Rezolvare(i_vecin, j_vecin, pas + 1);
matrice[i_vecin][j_vecin] = 0;
}
}
}
}

int main()
{
Citire();
Rezolvare(poz_init_X, poz_init_Y, 2);
return 0;
}

Enuntul problemei:
Se da o tabla de sah cu dimensiunea NxN. Un cal se gaseste in linia 1 si coloana 1. Gasiti un sir de
mutari ale calului astfel incat acesta sa acopere intreaga tabla de sah fara a trece printr-o casuta de 2 ori.
Acesta problema este foarte asemanatoare cu problema labirintului. Doar ca difera ceva, de data asta nu
ne mai deplasam nord – sud – est – vest, ne deplasam cum se deplaseaza calul pe tabla de sah.

Toate mutarile posibile

Am incercat mai sus sa desenez toate mutarile posibile pe care le poate face calutul nostru. Daca
transpunem poza in doi vectori de directii, rezultatul este urmatorul:

#include <iostream>

using namespace std;

int n;

int matrice[105][105], xi = 0, yi = 0;

const int directii = 8;

const int di[directii] = {-2, -1, 1, 2, 2, 1, -1, -2};

const int dj[directii] = { 1, 2, 2, 1, -1, -2, -2, -1};

void Citire()

cin >> n;

cin >> xi >> yi;

matrice[xi][yi] = 1;
}

bool isFull()

for(int i = 0; i < n; i++)

for (int j = 0; j < n; j++)

if (matrice[i][j] == 0)

return false;

return true;

void Solutie()

static int w = 1;

cout << "Solutia nr. " << w << ": \n";

for(int i = 0; i < n; i++)

for(int j = 0; j < n; j++)

cout << matrice[i][j] << " ";

cout << "\n";

w ++;

cout << "\n\n";

bool isOK(int i, int j)

{
if(i > n - 1 || i < 0)

return false;

if(j > n - 1 || j < 0)

return false;

if(matrice[i][j])

return false;

return true;

void Rezolvare(int x, int y)

static int r = 2;

if(isFull())

Solutie();

//exit(1);

return ;

for(int i = 0; i < directii; i++)

int i_vecin = x + di[i];

int j_vecin = y + dj[i];

if (isOK(i_vecin, j_vecin))

matrice[i_vecin][j_vecin] = r++;

Rezolvare(i_vecin, j_vecin);

matrice[i_vecin][j_vecin] = 0;

r--;
}

int main()

Citire();

Rezolvare(xi, yi);

return 0;

Functia bool isOK(int x, int y)

 Primeste ca si parametrii doua numere intregi x si y (sunt numere intregi deoarece pot sa primeasca si -
1, altfel le-am fi declarat „unsigned int”)
 Functia noastra verifica prima oara daca noile coordonate sunt in-afara matricei
 De asemenea, casuta este respinsa daca a mai fost vizitata in trecut (valoarea mai mare ca 1)

Functia bool isFull()

 Verifica daca toate casutele sunt diferite de 0


 Cele doua for-uri pot fi inlocuite cu o conditie de genu
o if(numar_mutare_curenta >= n)
return false;

Functia void Rezolvare(int x, int y)

 Este o functie recursiva ce parcurge pe rand vecinii, iar mai apoi se intoarce de unde a plecat –
similar algoritmului lui Lee
 Aceasta functie verifica pe rand toti cei 8 vecini. In cazul in care casuta poate fi vizitata, aceasta functie
o viziteaza, iar cand se intoarce din recursivitate marcheaza casuta cu „0” (casuta nevizitata)

Daca doriti sa generati doar o solutie, decomentati linia cu exit(1);

https://tutoriale-pe.net/problema-calului-in-c-backtracking/

http://docerp.ro/modelling_chess

Вам также может понравиться