标签:
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