回溯问题二:八皇后问题

程序设计五大思想之一,回溯。接下来两天要用回溯解决以下问题:
(1)八皇后问题
(2)0-1背包问题
(3)旅行售货员问题
(4)装载问题
(5)迷宫问题
(6)图的m着色问题
(7)排列组合问题

问题一:八皇后问题
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?有趣的是,数学家高斯认为有96种方案,象棋高手认为有40种方案,计算机学家解出92种方案。本篇用C语言解出92种解:

程序设计思路:
把位置定义成结构体,c[i].x表示行,c[i].x表示列,i从第0行开始,每一行因为要找一个皇后,故要找八次,也就是八次函数递归。每一行都从列0开始找,0到第8列依次找,找到了保存在c[i]进入下一行找,此时递归find_que(i+1);每一行找到了不代表这行就不找其他的了,还要找其他的,因为方案有很多种,这里体现回溯思想

#include <stdio.h>
typedef struct//每个位置定义成一个结构体类型,该位置由行x列y组成
{
    int x;
    int y;
} Location;
int cheak(int i,Location c[])
{
    int j;
    for(j=0; j<c[i].x; j++)
    {
        ///判断在不在行、列、正、负对角线上
        if((c[i].x==c[j].x)||(c[i].y==c[j].y)||((c[j].y-c[i].y)==(c[j].x-c[i].x))||((c[j].y-c[i].y)==(-1*(c[j].x-c[i].x))))
        {
            return 0;
        }
    }
    return 1;
}
int count=0;//计数

void find_que(int i,int n,Location c[])
{
    if(i==n)//八个已经找到了,输出
    {
        int k;
        for(k=0; k<n; k++)
        {
            printf("(%d,%d) ",c[k].x,c[k].y);
        }
        t++;
        printf("\n");
    }
    else
    {
        int j=0;
        for(j=0; j<n; j++)
        {
            c[i].x=i;///行
            c[i].y=j;//列
            if(cheak(i,c))//每个位置都判断下
            {
                //printf("(%d,%d)---- ",c[i].x,c[i].y);
                find_que(i+1,n,c);///本行i已经找到了,那么进入下一行i+1找
            }
        }
    }
}
main()
{
    Location c[8];///可能所在的八个未知点
    find_que(0,8,c);
    printf("\n总数:%d",t);
}

猜你喜欢

转载自blog.csdn.net/weixin_42034217/article/details/84593726