我正在尝试解决C中的8皇后拼图问题。我遇到了递归搜索问题。该程序应该从给定的列开始:
execute(tabuleiro,8,0);
其中8是电路板中的列数,0是起始列。
当我从第0列开始时,这是有效的。当我向递归搜索发送任何其他列号时,程序只计入最后一列。例如,如果我选择从数字5列开始搜索,则从第5列到第7列搜索代码,之后它应该从0到4搜索,但它不会这样做。
如果我这样做:
execute(tabuleiro,8,3);
它只填充最后5个colummns,并且不会返回到第0列来完成解决方案:
另外,如何在此代码中选择女王的初始位置?就像我之前说过的那样,列是在代码中分配的,但我不确定如何选择正确的列。
代码有3个功能:一个用于显示板,另一个用于检查移动是否合法(因此一个女王不会攻击另一个),最后一个用于放置一个女王并重复其余董事会。
#include <stdlib.h>
#include <windows.h>
int sol = 0;
void viewtab(int tab[][8], int N)
{
int i,j;
for( i = 0; i < N; i++)
{
for( j = 0; j < N; j++)
{
if(tab[i][j] == 1)
printf("R\t");
else
printf("-\t");
}
printf("\n\n");
}
printf("\n\n");
system("pause");
printf("\n");
}
int secury(int tab[][8], int N, int lin, int col)
{
// this function is to check if the move is secury
int i, j;
// attack in line
for(i = 0; i < N; i++)
{
if(tab[lin][i] == 1)
return 0;
}
//attack in colune
for(i = 0; i < N; i++)
{
if(tab[i][col] == 1)
return 0;
}
// attack in main diagonal
//
for(i = lin, j = col; i >= 0 && j >= 0; i--, j--)
{
if(tab[i][j] == 1)
return 0;
}
for(i = lin, j = col; i < N && j < N; i++, j++)
{
if(tab[i][j] == 1)
return 0;
}
// attack in main secondary
for(i = lin, j = col; i >= 0 && j < N; i--, j++)
{
if(tab[i][j] == 1)
return 0;
}
for(i = lin, j = col; i < N && j >= 0; i++, j--)
{
if(tab[i][j] == 1)
return 0;
}
// if arrive here the move is secury and return true
return 1;
}
void execute(int tab[][8], int N, int col)
{
int i;
if(col == N)
{
printf("Solution %d ::\n\n", sol + 1);
viewtab(tab, N);
sol++;
return;
}
for( i = 0; i < N; i++)
{
// check if is secury to put the queen at that colune
if(secury(tab, N, i, col))
{
// insert the queen (with 1)
tab[i][col] = 1;
// call recursive
execute(tab, N, col + 1);
// remove queen (backtracking)
tab[i][col] = 0;
}
}
}
int main()
{
int i, j, tabuleiro[8][8];
for (i = 0; i < 8; i = i + 1)
for (j = 0; j < 8; j = j + 1) tabuleiro[i][j] = 0;
execute(tabuleiro,8,0);
return 0;
}
答案 0 :(得分:1)
搜索总是在最右边的列中停止,因为你专门告诉它停在那里:
void execute(int tab[][8], int N, int col)
{
int i;
if(col == N)
{
printf("Solution %d ::\n\n", sol + 1);
viewtab(tab, N);
sol++;
return;
}
查看您的终止条件:您根据最高列号检查当前列,然后停在那里。
如果要返回第0列,则必须更改循环逻辑。例如,让 col 达到N,此时将其重置为0,然后让它继续,直到达到原始值。另一种方法是继续,直到放置的皇后计数为N.
您以相同的方式选择初始点:您选择第一个并进行递归调用。如果最终导致解决方案,则打印它。如果没有,你的最高呼叫将继续到电路板的下一行(线路)并将第一个女王放在那里。
这已经在您的主要逻辑中。当电路板为空时,确保 secury 将返回 true ,而不是 false 或抛出错误。
答案 1 :(得分:-1)
一个。你可以把第一个女王放在(0,0)。 B.并从(0,0)开始搜索。 C.我认为没有必要开始寻找其他指数。 成功!!