八皇后问题

来源:互联网 发布:java.util.*是什么包 编辑:程序博客网 时间:2024/06/18 17:06

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

回溯算法:回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:
1、定义一个解空间,它包含问题的解。
2、利用适于搜索的方法组织解空间。
3、利用深度优先法搜索解空间。
4、利用限界函数避免移动到不可能产生解的子空间。

算法思想:用顺序栈存放棋盘中摆放棋子的位置,栈的层数代表棋盘中的列数,栈每一层内的数值代表棋子在这一列的行数。此时只需要考虑任意两列的棋子不在同一斜线上即可。

程序运行截图(为了方便截图,选取的N为4)
这里写图片描述
程序代码

#include<stdio.h>#include<stdlib.h>#define STACKSIZE 100#define INCREMENT 10#define ERROR -1#define CHESSBOARD_MAX 8//棋盘最大为8*8int chess[CHESSBOARD_MAX][CHESSBOARD_MAX] = { 0 };//初始化棋盘int sum = 0;//方法数             //先利用栈存放棋子摆放位置,再在二维数组中构建棋盘typedef struct SqStack{    int*top;    int*base;    int stacksize;}SqStack;int InitStack(SqStack&S){    S.base = (int*)malloc(sizeof(int));    S.top = S.base;    S.stacksize = STACKSIZE;    return 0;}void Push(SqStack&S, int e){    *S.top++ = e;}void OUT(SqStack&S){    S.top--;}int judge(SqStack S)//判断函数,判断棋子的摆放位置是否合理,如果合理则返回1{    int *p;    p = S.base;    for (; p< S.top - 1; p++)        if (*p == *(S.top - 1) || abs(*p - *(S.top - 1)) == S.top - p - 1)            return 0;    return 1;}void PutQueen(int x, int boardsize, SqStack&S){    void Printboard(SqStack S, int boardsize);    int i;    if (!x)        InitStack(S);    for (i = 0; i < boardsize; i++)    {        Push(S, i);        if (judge(S))//判断皇后位置        {            if (x == boardsize - 1)                Printboard(S, boardsize);            else                PutQueen(x + 1, boardsize, S);//递归        }        OUT(S);//如果不成立则退回来    }}void Printboard(SqStack S, int boardsize)//输出棋盘{    //利用一个值为0的二维数组,将栈内元素存放进去    int *p;    int line, row;    p = S.base;    while (p != S.top)    {        chess[p - S.base][*p] = 1;//p-S.base 代表列数,*p为行数        p++;    }    for (row = 0; row < boardsize; row++)    {        for (line = 0; line < boardsize; line++)        {            if (!chess[line][row])                printf("□");            else                printf("■");        }        printf("\n");    }    sum++;    for (row = 0; row < boardsize; row++)//重置二维数组        for (line = 0; line < boardsize; line++)            chess[line][row] = 0;    printf("\n");}int main(){    SqStack S;    int n;    while (1)    {        printf("本程序为N皇后问题\n请先输入N的值(1~8):");        scanf("%d", &n);        if (n>0 && n <= 8)            break;        printf("输入无效,请重新输入\n");    }    PutQueen(0, n, S);    printf("%d皇后问题一共有%d种放置方法\n\n", n, sum);    system("pause");}
    -
1 0
原创粉丝点击