C 皇后拼图4x4

C 皇后拼图4x4,c,C,我试图解决在4x4矩阵中放置4个皇后的皇后问题。我知道这可以用回溯算法解决。然而,我还没有研究过这个问题,我正试图用我现有的知识来解决它。所以,我试图在4x4矩阵中生成所有可能的皇后组合,并只打印一个不能相互抵消的组合 1) 对于生成所有组合,我使用rand函数 然而,有明显的错误,在我的上述编码。有些输出只有三个“1”,而不是四个“1”。我无法消除这个问题 #include <stdio.h> #include <stdlib.h> #include <time.

我试图解决在4x4矩阵中放置4个皇后的皇后问题。我知道这可以用回溯算法解决。然而,我还没有研究过这个问题,我正试图用我现有的知识来解决它。所以,我试图在4x4矩阵中生成所有可能的皇后组合,并只打印一个不能相互抵消的组合

1) 对于生成所有组合,我使用rand函数

然而,有明显的错误,在我的上述编码。有些输出只有三个“1”,而不是四个“1”。我无法消除这个问题

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

main()
{
    srand(time(NULL));
    int ar[30][30], i , j , a , b , c = -1, d = -1, k = 0;  

    while (1)
    {
        for (i = 0 ; i < 4 ; i++)
        {
            for (j = 0 ; j < 4 ; j++)
            {
                ar[i][j] = 0;
            }
        }

        for (i = 0 ; i < 2 ; i++)
        {
            for (j = 0 ; j < 2 ; j++)
            {
                a = rand() % 3 ;
                b = rand() % 3 ;
                if (a != c || b != d)
                {
                    ar[a][b] =  1 ; // here 1 = Queen 
                    c = a ;
                    d = b;
                }
            }
        }
    }  
}
#包括
#包括
#包括
main()
{
srand(时间(空));
int ar[30][30],i,j,a,b,c=-1,d=-1,k=0;
而(1)
{
对于(i=0;i<4;i++)
{
对于(j=0;j<4;j++)
{
ar[i][j]=0;
}
}
对于(i=0;i<2;i++)
{
对于(j=0;j<2;j++)
{
a=rand()%3;
b=rand()%3;
如果(a!=c | | b!=d)
{
ar[a][b]=1;//这里1=Queen
c=a;
d=b;
}
}
}
}  
}

2) 另外,是否有任何方法可以仅使用这些方法来降低时间复杂度

使用数组本身,而不是使用临时变量检查数组是否已填充

    for (i = 0 ; i < 2 ; i++)
    {
        for (j = 0 ; j < 2 ; j++)
        {
            a = rand() % 3 ;
            b = rand() % 3 ;
            if (ar[a][b] == 0)
            {
                ar[a][b] =  1 ; // here 1 = Queen 
            }
        }
    }
(i=0;i<2;i++)的

{
对于(j=0;j<2;j++)
{
a=rand()%3;
b=rand()%3;
如果(ar[a][b]==0)
{
ar[a][b]=1;//这里1=Queen
}
}
}
您的问题是,内部循环将执行4次,您只能使用变量
c
d
控制1次重复

假设
a
是1,
b
是1:你使
c=1
d=1

然后
a
是2,
b
是1。。。使
c=2
d=1

然后,如果a为1,b又为1,则无法检查是否存在重复。

(1)您只检查皇后是否与上次放置的皇后不在同一个正方形上。删除变量
c
d
,检查
ar[a][b]
是否仍然为零

(2) 您的分散方法将产生许多未命中的设置。特别是,因为你没有强制规定在同一级别上不能有任何女王。(此外,
rand()%3
生成0到2之间的随机值,包括0到2。这样,您将永远无法获得无威胁的配置。)

如果要使用random()方法,可以使用一维数组,其中索引是秩,数字是皇后所在的文件。然后从以下几点开始:

int queen[4] = {0, 1, 2, 3};

然后洗牌数组。对于4个皇后,这将产生4个!=24种可能的配置。你可以试着系统地遍历它们。

以下是一段时间前提出的针对8皇后问题的暴力回溯代码。只需将8改为4:

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);
}
void printBoard(int board[8][8])
{
    int i,j;
    printf("  ");
    for (j=0; j<8; j++) printf(" %1d",j+1); printf("\n");

    for (i=0; i<8; i++) {
        printf("%1d ",i+1);
        for (j=0; j<8; j++)
            printf(" %1c", board[i][j]==0? '-':'*');
        printf("\n");
    }
}
int-checkBoard(int-board[8][8]);
国际货币基金组织(国际货币基金组织[8][8],国际货币基金组织);
无效印制板(集成电路板[8][8]);
国际八国集团(无效)
{
国际板[8][8];
memset(板,0,尺寸(内部)*64);
国际单项体育联合会(国际单项体育联合会,0)){
印刷板;
申报表(1);
}
返回(0);
}
国际区(国际区[8][8],国际区)
{
int i,j;

对于(i=0;我在代码中“随机生成所有组合”是一个坏主意,因为您可能永远不会生成解决方案。@Paul我同意也应该有一个不同的解决方案,但如果随机数生成器是统一的,它可能不是最快的,但从长远来看可能是(应该)工作也一样…我假设问题可能是a和b都使用了唯一的生成器。你不能使用置换和递归函数吗?如果你把皇后放在对角线上,那么你在上/右角做所有置换:2x2,然后存储它们,然后切换索引2,3,使用之前存储的置换排列…等等..嗯..我很想计算缩放比例…但对于4x4来说可能仍然是合理的。另一方面,如果你想打印它们,排列的数量不应该那么高;)