八皇后问题

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;
}

回溯法效率较高

你可能感兴趣的:(八皇后问题)