标签:
a[i]表示八个棋子,i表示所在行,a[i]表示所在列
各个棋子不能横向、纵向、对角线在一条直线上。
因为我们以行为单位摆放棋子,所以各个棋子一定不在同一行。
对于不在纵向:a[i] != a[j]
对角线分为两种情况,左上右小和左下右上:
左上右下:a[i] -i!= a[j]-j
左下右上:a[i]+i!= a[j]+j
解法1:
遍历,遍历8^8种情况,每种情况加以判断,满足则+1
#include <stdio.h> int main() { int num = 0; int a[8], i, j; int flag = 0; for (a[0] = 0;a[0] <8;a[0]++) for (a[1] = 0;a[1] <8;a[1]++) for (a[2] = 0;a[2] <8;a[2]++) for (a[3] = 0;a[3] <8;a[3]++) for (a[4] = 0;a[4] <8;a[4]++) for (a[5] = 0;a[5] <8;a[5]++) for (a[6] = 0;a[6] <8;a[6]++) for (a[7] = 0;a[7] <8;a[7]++) { flag = 0; for (i = 0;i < 8 && flag == 0;i++) for (j = i+1;j < 8 && flag == 0;j++) { if (a[i] == a[j]) flag = 1; if (a[i] - i == a[j] - j) flag = 1; if (a[i] + i == a[j] + j) flag = 1; } if (flag == 0) num++; } printf("%d\n", num); }
此种方法效率较低
解法2:
回溯法,通过函数递归调用
#include <stdio.h> #define MAX 8 int check(int num); void find(int row); int queen[MAX]; int num; int main() { num = 0; find(0); printf("%d\n", num); } //用于深度搜索,每次深入一层,row+1,直到row=max-1 void find(int row) { int i, j; for ( i = 0;i < MAX;i++) { queen[row] = i; if (check(row)) if (row == MAX -1) num++; else find(row+1); } } //判断目前各个棋子的位置是否安全 int check(int num) { int i, j; for(i = 0;i < num;i++) //开始认为,判断一维数组存在两两相等,需要两层循环,但此处不需要,因为如果之前数组满足不存在两两相等情况, //若加入新数字,只需要判断新数字与数字其他数字的关系,不必再多余判断 //for (j = i+1;j <= num;j++) if (queen[i] == queen[num] || queen[i] -i == queen[num] - num || queen[i] + i == queen[num] + num ) return 0; return 1; }
回溯法效率较高
标签:
原文地址:http://my.oschina.net/u/2313065/blog/486748