我正试图解决这个女王问题,将4个女王放在4x4矩阵中。我知道它可以用回溯算法解决。但是,我还没有研究过这个,我正试图用我目前的知识解决它。所以我想要的是在4x4矩阵中生成Queen的所有可能组合,并且只打印一个不能相互抵消的组合。
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;
}
}
}
}
}
2)还有什么办法可以只使用这些方法来降低时间复杂度?
答案 0 :(得分:1)
不使用临时变量来检查数组是否已填充,而是使用数组本身!
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
}
}
}
您的问题是内循环将执行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 :(得分:1)
(1)您只检查女王与您放置的最后一个女王放在同一个方格上。删除变量c
和d
,然后检查ar[a][b]
是否仍为零。
(2)你的分散方法会产生许多错过的设置。特别是,因为你没有强制执行,所以不能在同一等级和档案上的任何皇后。 (此外,rand() % 3
产生从0到2的随机值,包括在内。你永远不会以这种方式获得非威胁配置。)
如果你想使用你的随机(bogosort)方法,你可以使用一维数组,其中索引是排名,数字是皇后所在的文件。然后你开始:
int queen[4] = {0, 1, 2, 3};
并随机播放数组。对于4个皇后,这将产生4个! = 24种可能的配置。您可以尝试系统地迭代它们。
答案 2 :(得分:0)
以下是前面提到的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");
}
}