代码+解释说明+心得 (按顺序来的)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int longitudinal[100];
int queen[100][100];
bool place (int); /*找到皇后合适的列位置*/
void Queen (int); /*找到所有皇后合适的位置,并矩阵输出*/
int main(int argc, char *argv[]) {
int num;
printf ("Please input the number of Queens:\n");
scanf ("%d", &num);
Queen (num);
return EXIT_SUCCESS;
}
/*检索皇后 Q 放置在 longitudinal[Q] 列是否发生冲突*/
bool place (int Q) {
int i;
for (i = 1; i < Q; i++)
if(longitudinal[Q] == longitudinal[i] || abs(Q-i) == abs(longitudinal[Q] -longitudinal[i]))
return true;
return false;
}
/*回溯,找出所有皇后 Q 合适的位置,并矩阵输出*/
void Queen(int num) {
int i, j;
int Q = 1;
int ways = 0;
memset (longitudinal, 0, sizeof(int)*num); /*初始化数组 Q*/
while(Q >= 1) {
longitudinal[Q] = longitudinal[Q] + 1; /*在下一列放置第 Q 个皇后*/
while(longitudinal[Q] <= num && (place(Q))) {
longitudinal[Q] = longitudinal[Q]+1; /*检索下一列*/
}
if(longitudinal[Q] <= num && (Q == num)) { /*得到一个,则输出一个*/
ways++;
printf ("\n%d\n", ways);
memset (queen, 0, sizeof(queen)); /*初始化数组queen*/
for(i = 1; i <= num; i++) { /*若时皇后,则为1,否则,为0*/
for (j = 1; j <= num; j++) {
if (longitudinal[i] == j) {
queen[i][j] = 1;
}
}
}
for (i = 1; i <= num; i++) {
for (j = 1; j <= num; j++)
printf ("%d ", queen[i][j]);
printf ("\n");
}
}
else if (longitudinal[Q] <= num && Q < num) {
Q = Q + 1; /*放置下一个皇后Q+1*/
}
else {
longitudinal[Q] = 0; /*本个皇后位置初始为0,回到上个皇后,向后重新选位(回溯)*/
Q = Q - 1;
}
}
}
解释说明:此代码先用一维数组Q找到皇后的合适位置,以二维数组longitudinal形式输出。先用一维数组的原因如下:数组Q的下标相当于时皇后的横坐标,而数组Q对应的值代表列,如:Q[1]=2,则为把第一个皇后放在第一行,第二列;如果用一维数组Q来找到皇后位置的话,在函数place中,判断是否在同行,列,对角线上时,无需判断是否同行。采用二维数组longitudinal的形式输出,更加形象直观的显示出所有皇后位置的摆放。
小编心得:在使用memset函数初始化时,注意参数的摆放位置,在初始化二维数组时,注意,要么用一重循环部分初始化,要么,不用循环,全部初始化,就像小编一样啦。当时,小编就米有用循环,结果直接初始化,结果,输出不对,等到明白原因时,顿时觉得,原来自己当时撒比的一下,就米有想到呢。下次要注意啦~ 还有就是,要么从头到尾用 i=1;i<=n;i++,要么,就从头到尾使用i=0;i<n;i++,防止越界或者别的。