问题描述:n*n棋盘,放n个皇后,皇后的一排,一列,两个对角线都不能存在另一个皇后。
回答:先写好棋盘,我们默认0是没放的,1是放置的用于区别。回溯的套路,一个皇后放好后,决定下一个皇后放哪儿,直到所有的皇后全部放好,打印。然后回溯,决定其他情况。
判断条件:皇后可以射击这一排这一列,两个对角线,从另一个角度是否是说,安放皇后时,这个点的横,竖,对角线都不能有其他皇后。利用Judge函数判断如果可以放的话,就令点a[t][j]为1,然后递归,递归返回后,取消这个点,也就是令a[t][j]='0';然后选择其他情况。
#include<stdio.h>
#include<string.h>
char a[50][50]; //棋盘
int n; //n皇后,n*n棋盘
int sum;
void backtracking(int t); //回溯,t是皇后第几个
int Judge(int t, int j);
int main(void)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
a[i][j] = '0'; //可以放则'0',不能放则为'1'
backtracking(1);
printf("sum=%d\n", sum);
return 0;
}
void backtracking(int t)
{
if (t == n+1) //皇后找好了
{
sum++;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
printf("%c ", a[i][j]);
printf("\n");
}
printf("---------------\n");
return;
}
for (int j = 1; j <= n; j++) //第t行第j列
{
if (Judge(t, j)) //返回1不能放,就continue
continue;
a[t][j] = '1';
backtracking(t + 1);
a[t][j] = '0';
}
}
int Judge(int t, int j) //可以放返回0,不能放返回1
{
int flag = 0;
for (int k = 1; k <= n; k++) //第k行第j个 ,判断列
if (a[k][j] == '1')
{
flag = 1;
break;
}
for (int k = 1; k <= n; k++) //第t行,第k个,判断行
if (a[t][k] == '1')
{
flag = 1;
break;
}
for (int c = t, d = j; c >= 0 && d >= 0; c--, d--) //判断左上角
if (a[c][d] == '1')
{
flag = 1;
break;
}
for (int c = t, d = j; c <= n && d <= n; c++, d++) //判断右下角
if (a[c][d] == '1')
{
flag = 1;
break;
}
for (int c = t, d = j; c <=n && d >= 0; c++, d--) //判断左下角
if (a[c][d] == '1')
{
flag = 1;
break;
}
for (int c = t, d = j; c >= 0 && d <= n; c--, d++) //判断右上角
if (a[c][d] == '1')
{
flag = 1;
break;
}
return flag;
}
作者:鲸住我了