♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ |
Com base nas informações do problema, vamos tentar reduzir o máximo possível o espaço de busca de modo a tornar a solução por força bruta viável. Abaixo discutimos algumas opções:
Considere uma matriz do tabuleiro 8x8, com índices de zero a sete
nas linhas e colunas.
Cada possível configuração das rainhas
no tabuleiro, dentro do espaço de busca considerado,
é representada por um vetor int linhas[8];
,
onde a i-ésima rainha Ri ocupa a posição
(x,y)=(i-1, linhas[i-1])
do tabuleiro.
(0, linhas[0])
.(1, linhas[1])
.(7, linhas[7])
.int linhas[8] = {0, 1, 2, 3, 4, 5, 6, 7};
corresponde a seguinte configuração:
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ | |||||||
♛ |
linhas
e
imprime todas as soluções do problema.
void Troca(int v[], int i, int j) { int tmp; tmp = v[i]; v[i] = v[j]; v[j] = tmp; }Também precisamos de uma função que verifica se uma dada permutação do vetor
linhas
corresponde a uma solução do problema.
Para isso, precisamos verificar as diagonais.
int SolucaoValida(int linhas[]){ int i; int x,y; int xx,yy; for(i = 0; i < 8; i++){ x = i; y = linhas[i]; xx = x; yy = y; while(1){ xx += 1; yy -= 1; if(xx > 7 || yy < 0) break; if(yy == linhas[xx]) return 0; } xx = x; yy = y; while(1){ xx -= 1; yy -= 1; if(xx < 0 || yy < 0) break; if(yy == linhas[xx]) return 0; } } return 1; }Precisamos também de uma função para imprimir as soluções encontradas:
void ImprimeSolucao(int linhas[]){ char tabuleiro[8][8]; int i,j; int x,y; static int nsols = 0; nsols++; printf("******** SOL: %d ********\n",nsols); for(i = 0; i < 8; i++) for(j = 0; j < 8; j++) tabuleiro[i][j] = '.'; for(i = 0; i < 8; i++){ x = i; y = linhas[i]; tabuleiro[y][x] = 'R'; } for(i = 0; i < 8; i++){ for(j = 0; j < 8; j++){ printf(" %c ",tabuleiro[i][j]); } printf("\n"); } }
int linhas[8] = {0, 1, 2, 3, 4, 5, 6, 7};
,
e, em seguida, chamamos a função recursiva
TestaPermutacoes
, responsável por gerar as
permutações, iniciando no índice zero (segundo
parâmetro da função).
void Solucoes8Rainhas() { int linhas[8]; int i; for(i = 0; i < 8; i++) linhas[i] = i; TestaPermutacoes(linhas, 0); }Na função
TestaPermutacoes
,
os elementos com índices menores que k
estão fixos. A função
deve gerar as permutações dos elementos
com índices maiores ou iguais a k.
Se k=8, então todos elementos estão fixos
e o vetor deve ser verificado e impresso (caso trivial).
Caso contrário, fixamos um novo elemento na posição k
e testamos as permutações a partir do índice k+1.
Repetimos esse processo fixando todos os possíveis
elementos na posição k.
void TestaPermutacoes(int linhas[], int k) { int i; if(k == 8) { if(SolucaoValida(linhas)) ImprimeSolucao(linhas); } else{ for(i = k; i < 8; i++) { Troca(linhas, k, i); TestaPermutacoes(linhas, k + 1); Troca(linhas, i, k); } } }
#include <stdio.h> #include <stdlib.h> /*Colocar aqui as funções anteriores*/ ... int main(){ Solucoes8Rainhas(); return 0; }