-
Notifications
You must be signed in to change notification settings - Fork 0
/
Backtracking.cpp
133 lines (99 loc) · 3.15 KB
/
Backtracking.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <vector>
#include <iostream>
#include <cmath>
#include <chrono>
#include <thread>
#include "Utils.h"
#include "Backtracking.h"
// ==================== SUDOKU=============== //
// método que verifica se uma determinada jogada é possível
// x é linha, y é coluna
bool is_possible_sudoku(std::vector<std::vector<int>>& grid, int x, int y, int n) {
for (int j = 0; j < grid.size(); j++){
if (grid[x][j] == n) { // fixa linha e varre as colunas p saber se ja tem esse valor lá
return false;
}
}
for (int i = 0; i < grid.size(); i++){
if (grid[i][y] == n) { //fixa coluna e varre linhas
return false;
}
}
int x0 = (x / 3) * 3;
int y0 = (y / 3) * 3;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (grid[x0 + i][y0 + j] == n) { // verifica se no quadrado tem número igual ao que estamos tentando inserir
return false;
}
}
}
return true;
}
bool solve_sudoku(std::vector<std::vector<int>>& grid, int x, int y) {
// verificar se solução está completa
if (x == grid.size() - 1 && y == grid.size() - 1) {
printSequenceSequence(grid);
//std::this_thread::sleep_for(std::chrono::milliseconds(x));
return true;
}
else {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (grid[i][j] == 0) { //verifica se a posição está livre
for (int k = 1; k <= 9; k++){ //valores possíveis
if (is_possible_sudoku(grid, i, j, k)) {
grid[i][j] = k;
//system("cls");
//printSequenceSequence(grid);
//std::this_thread::sleep_for(std::chrono::milliseconds(x));
solve_sudoku(grid, i, j); // tenta preencher as outras posições
grid[i][j] = 0; // desfaz para tentar outra solução possível
}
}
return false;
}
}
}
}
}
bool solve_sudoku(std::vector<std::vector<int>>& grid) {
return solve_sudoku(grid, 0, 0); // usuario passa a grade e começo preenchendo da posição 0,0
}
// ==================== N - QUEENS =============== //
bool is_possible_queen(std::vector<int>& queens, int col) { // fç auxiliar que verifica se podemos
// add a rainha em uma determinada posição
int row = queens.size();
for (int i = 0; i < queens.size(); i++){
if (queens[i] == col) { // verifica se já tem rainha na coluna que queremos add
return false;
}
}
for (int i = 0; i < queens.size(); i++){
// verifica se há ataque na diagonal
if (std::abs(queens[i] - col) == std::abs(row - i)) { // msm distancia da linha e coluna
return false;
}
}
return true;
}
bool s_nqueen(std::vector<int>& queens, int n) {
if (queens.size() == n) { // qdo a solução chega em n rainhas, quer dzr q concluiu
printSequence(queens); // imprimir a solução
return true;
}
else {
for (int i = 0; i < n; i++) { // colunas q podemos atribuir a soluç
if (is_possible_queen(queens, i)) { // testar as soluções
queens.push_back(i);
s_nqueen(queens, n); // resolver recursivamente p/ o restante
queens.pop_back(); // qdo ñ resolver, volta uma posição
}
}
return false; // não conseguiu soluç
}
}
void solve_nqueen(int n) { // tamanho do tabuleiro e de rainhas
std::vector<int> queens({});
s_nqueen(queens, n);
}