Foi-me feita a seguinte pergunta em uma entrevista hoje e penso nisso desde então. Não consegui responder e não consegui encontrar uma solução online.
Dado um tabuleiro de xadrez com as dimensões X das rainhas Y e N, determine se é possível organizar essas rainhas no tabuleiro de modo que não possam atacar umas às outras.
Uma placa 2 x 3 com 2 rainhas tem uma solução para que o algoritmo retorne verdadeiro:
Q . .
. . Q
Estou procurando uma abordagem de programação para esse quebra-cabeça, não apenas maneiras de resolvê-lo no papel, por exemplo.
algorithms
puzzles
chess
Entrevistado
fonte
fonte
Respostas:
Este não é (IMO) um problema muito interessante do ponto de vista da programação. Você pode criar um algoritmo recursivo que tente todos os arranjos, algo como isto:
Se você pensar um pouco sobre o problema, perceberá que não há como encaixar N rainhas em um quadro em que X <N ou Y <N, porque isso exigiria que pelo menos duas rainhas terminassem na mesma fila ou arquivo, e eles atacariam um ao outro. Se você ler sobre o problema das n-rainhas, aprenderá rapidamente que sempre é possível colocar N rainhas em uma placa NxN para N> 3. Agora sabemos que a resposta é NÃO para (X <N ou Y <N) e SIM para (X> = N e Y> = N, N> 3). Tudo o que resta são os casos especiais:
Portanto, agora nossa agradável função recursiva se torna uma função simples que apenas compara N a X e Y e retorna um resultado fixo. Isso é ótimo do ponto de vista do desempenho, pois você pode obter uma resposta em tempo constante. Não é tão bom do ponto de vista de programação, porque você percebe, neste momento, que a pergunta é realmente mais sobre o quão bem você pode resolver quebra-cabeças do que sobre sua capacidade de escrever uma função recursiva.
(E garoto, oh garoto, eu realmente espero que não tenha cometido algum erro estúpido na minha resposta. ;-)
fonte
That's great from a performance point of view, since you can get an answer in constant time. It's not so great from a programming point of view because you realize, at this point, that the question is really more about how well you can solve puzzles than it is about your ability to write a recursive function.
Na verdade, acho que o entrevistador estava esperando por essa solução O (1) porque, em última análise, é melhor e não é óbvia para muitas pessoas. O problema do nxn queen está em todos os cursos de programação como um exercício de recursão - muitas pessoas não pensam mais profundamente ao ver esse problema novamente.Se o entrevistador pediu para você escrever o código do problema, acho que não é justo. O algoritmo requer trabalho. No entanto, se a ideia era mostrar ao entrevistador as classes, métodos ou alguns conceitos que você precisaria usar ou algo semelhante, então pode ser uma pergunta justa.
O problema é um problema clássico de Ciência da Computação e é discutido em muitos desses livros. Uma excelente explicação, com animação e 12 soluções diferentes, juntamente com algum código, pode ser encontrada aqui:
http://en.wikipedia.org/wiki/Eight_queens_puzzle
Também código pode ser encontrado aqui: http://www.codeproject.com/KB/java/EightQueen.aspx
Não se sinta mal com isso, como eu disse, não é fácil.
fonte
Isso é realmente mais um comentário, mas não se encaixa lá ...
Um tabuleiro de xadrez tem quadrados 8x8, nem mais nem menos (essas perguntas sempre me incomodam com a abordagem de um tabuleiro de xadrez personalizado).
Mas de qualquer maneira, se você tem um tabuleiro de xadrez x * y, n rainhas e considera que a rainha "pega" esses campos
você pode apenas criar uma matriz bidimensional e "sinalizar" todos os campos que uma rainha ataca. Em seguida, coloque o outro (do meio do quadro), sinalize os campos restantes e assim por diante ... até executar campos ou rainhas.
Essa é, obviamente, uma abordagem muito simplificada, pois, se posicionada de maneira incorreta, eu acho que o número máximo de rainhas varia.
Hmm, acabei de encontrar isso também - problema de 8 rainhas.
fonte
Basicamente, o algoritmo de retorno funciona assim:
Crie uma matriz X por Y. Defina todos os quadrados para esvaziar.
Defina a contagem da rainha como zero.
Defina sua posição atual para (1,1)
Veja se você pode colocar uma rainha na posição atual.
Se puder, defina Matriz (X, Y) como rainha, aumente a contagem de damas. Se você colocou toda a rainha, pare , você tem uma solução.
Se a posição atual não for (X, Y), aumente a posição atual e vá para a etapa 4.
Encontre a rainha na última posição (a que vier por último na ordem em que você aumenta as posições). Defina a posição atual para a posição da rainha, remova-a e diminua a contagem de damas.
Se a contagem de damas for zero, pare , não há solução.
Incremente a posição atual.
Vá para o passo 4.
fonte
Adicionando às outras respostas: a criação de uma matriz bidimensional apenas complica o código.
Você só precisa de um vetor do tamanho 8 para um tabuleiro de xadrez comum. Ou 8 + 1 se C 1ª posição for 0, apenas para simplificar o código, e lidar com 1-8 e não 0-7.
Se você pensa em x ser sua posição na matriz e y ser o conteúdo da posição. por exemplo, bordo [1] = 8 significa que a primeira rainha está em [1,8].
Dessa forma, você só precisa verificar a validação das colunas.
No momento da faculdade, me deparei com um livro muito antigo (anos 60?), Sobre algoritmos implementados no Dartmouth BASIC, que implementava o problema das 8 rainhas usando menos memória possível (sendo tão antiga, faz sentido).
Tanto quanto me lembro, ele usou a idéia de vetor e essencialmente bruta forçou todas as posições no quadro com dois ciclos FOR. Para verificar a validade da posição, ele usou um terceiro loop, um ciclo WHILE em cada posição volta no vetor e verifica um número igual ou uma fórmula usando uma operação tangente para verificar as diagonais.
Infelizmente, eu perdi a noção desse livro ...
O referido algoritmo encontrou todas as soluções para o problema n-queen.
fonte
Se você apenas tiver que escrever um algoritmo para determinar se esse arranjo existe, observe a pesquisa existente:
Oito rainhas do enigma na Wikipedia .
Você pode retornar trivialmente false se N> min (X, Y).
Depois de ler essa página, você retornará true se N <= min (X, Y) e 2, 3! = Min (X, Y).
O que deixa 2, 3 == min (X, Y) e N <= min (X, Y).
Bem, se N <min (X, Y), encontrar uma solução é trivial.
Se N == min (X, Y), existe apenas uma solução se max (X, Y)> N.
fonte
Obviamente, não há solução se N> min (X, Y). Caso contrário, você pode mostrar facilmente que não há solução para N = X = Y = 2, N = X = Y = 3. Para todos os outros casos, parece haver uma solução. O número de soluções parece aumentar à medida que N cresce.
Você pode encontrar uma solução através de pesquisa exaustiva com retorno: Coloque uma dama na primeira linha, coluna 1. Coloque uma dama na segunda linha, na primeira coluna que a rainha da linha 1 não pode alcançar. Coloque uma dama na segunda fila, etc. Se uma dama não puder ser colocada na fila k, remova-a e mova a dama na fila k-1 na próxima posição desocupada.
fonte