C 皇后拼图4x4
我试图解决在4x4矩阵中放置4个皇后的皇后问题。我知道这可以用回溯算法解决。然而,我还没有研究过这个问题,我正试图用我现有的知识来解决它。所以,我试图在4x4矩阵中生成所有可能的皇后组合,并只打印一个不能相互抵消的组合 1) 对于生成所有组合,我使用rand函数 然而,有明显的错误,在我的上述编码。有些输出只有三个“1”,而不是四个“1”。我无法消除这个问题C 皇后拼图4x4,c,C,我试图解决在4x4矩阵中放置4个皇后的皇后问题。我知道这可以用回溯算法解决。然而,我还没有研究过这个问题,我正试图用我现有的知识来解决它。所以,我试图在4x4矩阵中生成所有可能的皇后组合,并只打印一个不能相互抵消的组合 1) 对于生成所有组合,我使用rand函数 然而,有明显的错误,在我的上述编码。有些输出只有三个“1”,而不是四个“1”。我无法消除这个问题 #include <stdio.h> #include <stdlib.h> #include <time.
#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来说可能仍然是合理的。另一方面,如果你想打印它们,排列的数量不应该那么高;)