给定一个4x4的棋盘,要在棋盘上放置4个皇后。他们的位置有这样的要求,每一列,每一行,每一对角线都能有一个皇后。算法
你可能会对这个对角线有疑惑,其实就是每个小正方形的对角线都不能有皇后。能够看图理解一下。
数组
设皇后k摆放在x[k]的位置上,注意数组下标从0开始,0<=k<n且0<=x[k]<n。数据结构
这里用数组下标以及对应的值,模拟了一个棋盘的行和列。这是比较奇妙的地方,不须要二维数组了。code
算法:setQueen(n)
输入:皇后的个数n
输出:n皇后问题的解x[n]。解是一个数组。blog
#include <stdio.h> #include <cstring> #include <math.h> class Queen { private: int Place(int k); int *x; int num; public: Queen(int n); void setQueen(); void PrintQueen(); ~Queen(); }; Queen::Queen(int n) { x = new int[n]; memset(x, -1, n); //-1表示还没有摆放皇后 num = n; } Queen::~Queen() { delete[] x; } void Queen::setQueen() { int k = 0, count = 0; while (k >= 0) //摆放皇后k,注意0<=k<n { x[k]++; //在下一列摆放皇后k while (x[k] < num && Place(k) == 1) //发生冲突 x[k]++; //皇后k试探下一列,超出num将会跳出 if (x[k] < num && k == num - 1) //获得一个解 { printf("第%d个解:", ++count); PrintQueen(); } else if (x[k] < num && k < num - 1) //尚有皇后未摆放 k = k + 1; //准备摆放下一个皇后 else x[k--] = -1; //重置x[k],回溯,从新摆放皇后k } } //放置皇后。在一个位置上放置皇后,而后将结果返回。 int Queen::Place(int k) //考察皇后k放置在x[k]列是否发生冲突 { for (int i = 0; i < k; i++) if (x[i] == x[k] || abs(i - k) == abs(x[i] - x[k])) //根据对角线原则 return 1; //冲突返回1 return 0; //不冲突返回0 } //打印皇后的解 void Queen::PrintQueen() { for (int i = 0; i < num; i++) printf("%d\t", x[i] + 1); printf("\n"); } int main(void) { int n; printf("请输入皇后个数(n>=4):"); scanf("%d", &n); Queen Q(n); Q.setQueen(); return 0; }
这里面的代码是来自「数据结构C++王红梅版」string
也知道了不少新颖的点io
这里放一波我以前逻辑结构很混乱的代码(就能够求解到正确答案,可是输出的时机很难控制)class
#include <stdio.h> #include <string.h> #include <math.h> #define n 4 //设定n皇后的数目 int *x = new int[n]; void printA(); int place(int k); int main(void) { memset(x, -1, sizeof(int) * n); int k = 0; while (k > -1) { x[k]++; if (k < n && place(k) == 1) //不冲突,开始放置下一行 若是已是最后一行呢? { if (k < n - 1) k++; } else if (k < n || x[k] == n) //要回溯到上一行 { x[k] = -1; k--; } else if (k == n && x[k] < n) { //获得一组解答 printA(); } } return 0; } //在第k行放置皇后,返回1表明冲突,返回0表明不冲突 int place(int k) { for (; x[k] < n; x[k]++) { bool flag = true; for (int i = 0; i < k; i++) { if (x[k] == x[i] || (abs(k - i) == abs(x[k] - x[i]))) { flag = false; break; } } if (flag) return 1; } return 0; } void printA() { for (int i = 0; i < n; i++) { printf("%d ", x[i] + 1); } printf("\n"); }