n*n的棋盘上放n个皇后。最多有多少种放法。
int i;
for(i = 1 ; i < k ; i++)
if(abs(k-i) == abs(x[k] - x[i]) || x[k] == x[i])
return 0;
return 1;
int j;
if(i > n)
//如果最后一个皇后也放完了,即得到一个可行解。sum+1.
{
sum++;
return;
}
else
for(j = 1 ; j <= n ; j++)
{
x[i] = j;
//将第i个放在第j行上。即把x[i]的坐标改为j。
if(check(i))
//如果放置的这第i个皇后的前边(行列斜)没有其他皇后,那么继续放置下一个皇后。如果有,则j自加,即把第i个(列坐标为i)放在第j+1行。
dfs(i+1);
}
scanf("%d", &n);
dfs(1);
if(n == 0)
sum = 0;
printf("%d\n", sum);
return 0;
这个题类似于houseblocks,但此题不需要二维数组。用一个一维数组的数值表示行数,下标表示列数。即(x[i], i)。因为要放n个,所以必须一列有一个皇后,因此第几个皇后就放在第几列。
从第一个皇后开始(第一列),放在第一行,放完了以后进行判断,如果前边没有皇后,那么继续放下一个,如果有,放在第二行……用for循环j实现。直到放完了n个皇后,此时放法+1。之后,再回到上一层,即上一层的j变为j的下一个,也就是把上一个皇后再挪到下一行上,再往后进行……当这个皇后已经挪到第n行上以后,再回到上一层,继续进行……
(可行则进,不行则换,换不成则退)
这里的check函数比较巧妙。不用挨着判断行、列、主对角、副对角,假设前边的皇后坐标为(x[k], k), 要判断的为(x[i], i),那么不在主对角:x[k]+k!=x[i]+i,不在副对角:x[k]-k!=x[i]-i。综合:abs(x[k]-x[i])!=abs(k-i) && x[k]!=x[i]。而第几个皇后就在第几列,所以不用判断也知道不会在同一列上。
#include
#include
int n, x[10], sum;
int check(int k)
//某一点放置的坐标为(x[k], k).
{
}
void dfs(int i)
{
}
int main()
{
}