所以我必须做一个N皇后问题的修改版本,在那里我们得到了一个充满了棋子的棋盘的初始配置,我们需要找到我们可以拥有的最大数量的皇后,以便他们不会# 39;互相攻击输入由第一行中的整数组成,给出了板的尺寸(NxN),n行定义了棋盘的设置。字符将是'p'(意味着该位置已经有一个棋子)或'e'(意思是位置为空)。
例如,对于此输入,
5
epepe
ppppp
epepe
ppppp
epepe
输出为9。
这是我的代码,一切看起来都很清楚,但我不明白为什么它没有给出正确的输出
#include <stdio.h>
#include <malloc.h>
/* function headers */
void do_case(int);
int solve(char **,int,int);
int canPlace(char **,int,int,int);
/* Global vars */
int queens;
int main(void)
{
int n;
scanf("%d",&n);
getchar();
while( n != 0 )
{
do_case(n);
scanf("%d",&n);
getchar();
}
return 0;
}
void do_case(int n)
{
int i,j; //counters for input
//board configuration allocation
char **configuration = (char **)malloc(n*sizeof(char *));
for(i = 0 ; i < n ;i++ )
configuration[i] =(char *)malloc(n*sizeof(char));
queens = 0;
//get input
for( i = 0; i < n; i++ )
{
for( j = 0; j < n; j++ )
{
scanf("%c",&configuration[i][j]);
}
getchar();
}
//solve
solve(configuration,n,0);
printf("%d \n",queens);
}
//recursive solver
int solve(char **configuration,int N,int col)
{
int i,j;
//base case
if( col >= N )
return 1;
//consider this column
//try placing queen in non blocked spot in all rows
for(i = 0; i < N; i++)
{
if ( configuration[i][col] == 'e' && canPlace(configuration,N,i,col) )
{
//Place queen in configuration[i][col]
configuration[i][col] = 'q';
queens++;
//recursion on the rest
if( solve(configuration,N,col + 1) == 1 )
{
return 1;
}
//backtrack
configuration[i][col] = 'e';
queens--;
}
}
return 0;
}
//this function check if queen can be placed
int canPlace(char **configuration,int N, int row, int col)
{
int i, j;
/* Check this row on left side */
for (i = 0; i < col; i++)
{
if (configuration[row][i] == 'q')
{
return 0;
}
}
/* Check upper diagonal on left side */
for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
{
if ( configuration[i][j] == 'q')
{
return 0;
}
}
/* Check lower diagonal on left side */
for (i = row, j = col; j >= 0 && i < N; i++, j--)
{
if (configuration[i][j] == 'q')
{
return 0;
}
}
return 1;
}
答案 0 :(得分:0)
当棋子挡住了路,你不应该只是前往下一列,因为你可以在同一列中放置更多的皇后。您应该修改代码以在递归时传递行和列,并且只移动到下一个方块而不是下一个列。
此外,您的算法看起来像找到第一个解决方案而不是最佳解决方案。最初的皇后问题只关心一个可能的解决方案,但是对于修改过的问题,你需要确保检查所有解决方案并记住最好的解决方案。
此外,您的canPlace
功能错误。它根本不会占用典当。
答案 1 :(得分:0)
基本上,你的代码输出0是因为它要求我们在每一列中只放置一个皇后,这在你的例子中不是这样。
那就是说,算法存在多个问题(我并不认为列表是完整的,尽管可能是这样):
代码不考虑所有可能性:它只会找到第一种可能的排列,然后在单个“if(col&gt; = N)返回1;”之后退出搜索。相反,它应该像“if(col&gt; = N)更新单独变量中的最佳皇后值,然后返回0继续搜索”。
在“if(solve(configuration,N,col + 1)== 1)”行中,代码假定一列中不能有两个皇后。该调用应使用col
代替col + 1
,并以某种方式说明我们在当前列停止的位置。
要允许没有皇后的列,无条件调用“solve(configuration,N,col + 1)”应放在solve函数的某处。
当我们允许第2项时,应该修改函数canPlace以检查列。
每当找到pawn时,canPlace的循环都会中断。