我正在编写一个读取整数值(n)的程序,并创建一个包含这些维度(nXn)的国际象棋桌。然后,我必须看看是否有一种方法可以将n个皇后放置在这个板上,使得它们中没有一个可以相互攻击(对于那些不熟悉国际象棋的人,皇后区可以攻击同一列中的任何一块或者排成它们,以及任何穿过女王的对角线上的那块。这些值存储在一个数组(int board [n])中,最初设置为全-1。 board [0]中的值对应于第0列中的queen位于的行。最初,所有值都设置为-1,这意味着所述行中没有任何部分。
我正在尝试找到一种方法,我可以通过一种方法检查是否可以传递每个可能的坐标集(基本上每个可能的长度为n的数组,其值可以在0到n-1之间)这是布置碎片的有效方法,如果布局有效,它必须将该数组传递给可视化它的方法,如下所示:
* * Q *
Q * * *
* * * Q
* Q * *
检查和输出的方法已设置并正常工作,我只需要弄清楚如何生成存储该坐标的数组的所有可能排列。
编辑: 这是迄今为止的代码(12月6日下午2点更新):
#include <stdio.h>
#include <stdlib.h>
int permutations (int board[],int n, int counter, int index);
int check (int board[], int n);
int printout (int board[], int n, int isValid);
int main() {
int n, board[n];
while (1==scanf("%d", &n) && n > 0) {
int board[] = {-1};
int isValid = permutations(board,n, 0, 0);
printout(board, n, isValid);
}
return 0;
}
int permutations(int board[],int n, int counter, int index){
board[index] = counter;
int max = n-1;
if ((check(board, n) == 1) && (index == max)){
return 1;
}
if (check(board, n) == 1){
permutations(board, n, 0, ++index);
}
else if (check(board, n) == 0){
counter++;
}
if (counter == n){
return 0;
}
}
int check(int board[], int n){
int i,j;
int isValid = 1;
for (i=0; i<n && isValid; ++i) {
if (board[i]==-1) continue;
for (j=i+1; j<n && isValid; ++j) {
if (board[j]==-1) continue;
if ( board[i] == board[j] ||
board[i]-board[j] == i-j ||
board[i]-board[j] == j-i )
isValid = 0;
}
}
return isValid;}
int printout(int board[], int n, int isValid){
int i,j;
putchar('\n');
for (i=n-1; i>=0; --i) {
for (j=0; j<n; ++j) {
if (j>0) putchar(' ');
putchar( board[j]==i ? 'Q' : '.' );
}
putchar('\n');
}
puts( isValid ? "valid configuration" : "invalid configuration" );
return 0;
}
答案 0 :(得分:0)
提示你的作业(递归):
从空白板开始,然后调用递归例程。在棋盘上迭代,试图把一个女王放在上面。如果受到攻击则继续。否则请用电路板打电话给自己(现在还有一个女王)。在棋盘上迭代,试图把一个女王放在上面。如果受到攻击则继续。请自己打电话......
如果你已经达到6个皇后,则返回“成功”并展开递归。
如果在任何时候你不能在棋盘上放置另一个女王,请返回“失败”,移除女王并继续你自己所在地的迭代。
这是一种“蛮力”的方法。
答案 1 :(得分:0)
此代码有效(这是您的作业):
int checkBoard(int board[8][8]);
int putQueens(int board[8][8], int nQueens);
void printBoard(int board[8][8]);
int eightQueens(void)
{
int board[8][8];
memset(board, 0, sizeof(int)*64);
if (putQueens(board, 0)) {
printBoard(board);
return (1);
}
return(0);
}
int putQueens(int board[8][8], int nQueens)
{
int i, j;
for (i=0; i<8; i++) {
for (j=0; j<8; j++) {
if (board[i][j]==0) {
board[i][j]= 1;
if (checkBoard(board)) {
if (nQueens==7) return(1);
if (putQueens(board, nQueens+1)) return(1);
}
board[i][j]= 0;
}
}
}
return(0);
}
int checkBoard(int board[8][8])
{
int i, j;
for (i=0; i<8; i++) {
for (j=0; j<8; j++) {
if (board[i][j]) {
int ii, jj;
for (ii=i+1; ii<8; ii++) {
if (board[ii][j]) return(0);
}
for (jj=j+1; jj<8; jj++) {
if (board[i][jj]) return(0);
}
for (ii=i+1, jj=j+1; ii<8 && jj<8; ii++, jj++) {
if (board[ii][jj]) return(0);
}
for (ii=i-1, jj=j-1; ii>0 && jj>0; ii--, jj--) {
if (board[ii][jj]) return(0);
}
for (ii=i-1, jj=j+1; ii>0 && jj<8; ii--, jj++) {
if (board[ii][jj]) return(0);
}
for (ii=i+1, jj=j-1; ii<8 && jj>0; ii++, jj--) {
if (board[ii][jj]) return(0);
}
}
}
}
return (1);
}
我对checkBoard不满意;它可以变得更优雅。 (你的作业)。
所以你已经学会了:请发表评论,解释你的代码出错的地方以及你从上面的代码中学到了什么。
答案 2 :(得分:0)
main()
中的边际错误:在输入board[n]
之前,不要定义变量长度数组n
。
现在算法:对于分配的任务(在棋盘上放置n
个皇后),生成包含少于n
个皇后的布局是没有意义的。因此,使用可能重新排列为有效布局的一些排列初始化board
;我在下面选择了{ 0, 1, 2 .. n-1 }
。我重写了函数permutations()
,希望生成数组的所有可能的排列 board[]
,,如果有一个有效的布局,...传递数组到一个可视化它的方法(您的原始printout()
)。此外,该函数为有效布局增加了一个计数器 - 我发现计数因n
的不同值而有所不同。
int n, counter; // counter: counts valid layouts found
void permutations(int board[], int j)
{ // generate all possible permutations of board[0..j-1]
int i = --j;
if (i <= 0)
{ // arrived at one permutation - check it, and print if valid
if (check(board, n)) ++counter, printout(board, n, 1);
return;
}
permutations(board, i);
while (i--)
{
int k, x;
for (k = j; k > i; --k)
if (board[i] == board[k]) break;
if (k > i) continue;
x = board[i], board[i] = board[j], board[j] = x;
permutations(board, j);
x = board[i], board[i] = board[j], board[j] = x;
}
}
int main()
{
while (1==scanf("%d", &n) && n > 0)
{
int board[n], i;
for (i = 0; i < n; ++i) board[i] = i;
counter = 0, permutations(board, n);
printf("%d valid configurations\n", counter);
}
return 0;
}