八皇后问题

来源:互联网 发布:windows 8.1 64位 iso 编辑:程序博客网 时间:2024/06/09 22:23

百度百科关于八皇后问题的说明:

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。

废话不多说,直接贴代码:

#include "stdio.h"#include "string.h"// ----------------------------------------------------------------------------//                 definition// ----------------------------------------------------------------------------#define QN_NUM              8#define AREA_X_MAX          8#define AREA_Y_MAX          8// ---------------------------------------------------------------------------//                 local type// ----------------------------------------------------------------------------// basic typetypedef unsigned char   BYTE;typedef unsigned short  WORD;typedef unsigned long   DWORD;// BOOLtypedef enum{    FALSE = 0,    TRUE}BOOL;// pos typedef struct{    BYTE by_x;    BYTE by_y;}T_Pos, *PT_Pos;// queentypedef struct {    BYTE  by_sn;          // sn     T_Pos t_pos;          // pos}T_QN, *PT_QN;// area nodetypedef struct {    T_Pos t_pos;    BOOL  b_active;}T_AN, *PT_AN;// ---------------------------------------------------------------------------//                 func part// ----------------------------------------------------------------------------// ------------------------------------// init queen and area// ------------------------------------void Set_Default_Val(PT_QN pt_qn, PT_AN pt_an){    BYTE  by_i      = 0;    BYTE  by_j      = 0;    PT_AN pt_an_tmp = NULL;    PT_QN pt_qn_tmp = NULL;    // init area    for(by_i=0 ; by_i<AREA_X_MAX ; by_i++)    {        for(by_j=0 ; by_j<AREA_Y_MAX ; by_j++)        {            pt_an_tmp = pt_an + by_i * AREA_Y_MAX + by_j;            pt_an_tmp->b_active   = TRUE;            pt_an_tmp->t_pos.by_x = by_i;            pt_an_tmp->t_pos.by_y = by_j;        }    }    // init queen    for(by_i=0; by_i<QN_NUM ; by_i++)    {        pt_qn_tmp             = pt_qn + by_i;        pt_qn_tmp->by_sn      = by_i;        pt_qn_tmp->t_pos.by_x = 0;        pt_qn_tmp->t_pos.by_y = 0;    }}// ------------------------------------// print qn// ------------------------------------void Print_QN(BYTE by_rslt_sn, PT_QN pt_qn){    BYTE by_i, by_j;    BYTE by_sn;    BYTE aby_line[100];    BYTE aby_qn[20];    printf("\r\n - new rslt found - [%02d]\r\n", by_rslt_sn);    printf("-------------------------\r\n");    for(by_i=0 ; by_i<AREA_X_MAX ; by_i++)    {        for(by_sn=0 ; by_sn<QN_NUM ; by_sn++)        {            if(by_i == pt_qn[by_sn].t_pos.by_x)            {                memset(aby_line, 0x00, 100);                memcpy(aby_line, "|  |  |  |  |  |  |  |  |", strlen("|  |  |  |  |  |  |  |  |"));                                    memset(aby_qn, 0x00, 20);                sprintf(aby_qn, "Q%d", by_sn);                by_j = 1 + strlen("  |") * (pt_qn[by_sn].t_pos.by_y);                memcpy(&aby_line[by_j], aby_qn, strlen(aby_qn));                                printf("%s", aby_line);            }        }        printf("\r\n-------------------------\r\n");    }}// ------------------------------------// disable area node// ------------------------------------/* * 斜线的斜率固定(1:1). * 区域建模在第一象限 * y = x + b1 or y = -x + b2 */void Disable_Area_Node(const PT_QN pt_qn,                             PT_AN pt_an){    BYTE  by_i      = 0;    BYTE  by_j      = 0;    int   i_b1      = 0;    int   i_b2      = 0;    PT_AN pt_an_tmp = NULL;    // calc b1 & b2    i_b1 = pt_qn->t_pos.by_y - pt_qn->t_pos.by_x;    // (y - x)    i_b2 = pt_qn->t_pos.by_y + pt_qn->t_pos.by_x;    // (y + x)    for(by_i=0 ; by_i<AREA_X_MAX ; by_i++)    {        for(by_j=0 ; by_j<AREA_Y_MAX ; by_j++)        {            pt_an_tmp = pt_an + by_i * AREA_Y_MAX + by_j;            // 排除横纵坐标            if(  !(  (pt_qn->t_pos.by_x != by_i)                   &&(pt_qn->t_pos.by_y != by_j)))            {                pt_an_tmp->b_active = FALSE;               }                        // 排除y= x + b            if(pt_an_tmp->t_pos.by_y == (pt_an_tmp->t_pos.by_x + i_b1))             {                pt_an_tmp->b_active = FALSE;            }                        // 排除y=-x + b            if(pt_an_tmp->t_pos.by_y == (i_b2 - pt_an_tmp->t_pos.by_x))             {                pt_an_tmp->b_active = FALSE;            }        }    }}// ------------------------------------// search active node// ------------------------------------void Search_Active_Node_In_Row(const PT_AN pt_row_start,                                BYTE*       pby_num,                               BYTE*       pby_buf){    BYTE  by_i         = 0;    BYTE  by_buf_index = 0;    PT_AN pt_an_tmp    = NULL;    *pby_num  = 0;    pt_an_tmp = pt_row_start;        for(by_i=0 ; by_i<AREA_X_MAX ; by_i++)    {        if(pt_an_tmp->b_active)        {            pby_buf[by_buf_index] = by_i;            by_buf_index++;            (*pby_num)++;        }        pt_an_tmp++;    }}// ------------------------------------// copy an// ------------------------------------void Copy_AN(PT_AN pt_an1, PT_AN pt_an2){    BYTE  by_i;    BYTE  by_j;    PT_AN pt_an_temp1 = NULL;    PT_AN pt_an_temp2 = NULL;    for(by_i=0 ; by_i<AREA_X_MAX ; by_i++)    {        for(by_j=0 ; by_j<AREA_Y_MAX ; by_j++)        {            pt_an_temp1 = pt_an1 + by_i * AREA_Y_MAX + by_j;            pt_an_temp2 = pt_an2 + by_i * AREA_Y_MAX + by_j;                        pt_an_temp1->b_active = pt_an_temp2->b_active;            pt_an_temp1->t_pos    = pt_an_temp2->t_pos;        }    }}// ------------------------------------// match queen in a single line// ------------------------------------/* * search direction: * row 0 ------> * row 1 ------> *  . *  . * row 7 ------> * */void Match_In_Row(PT_AN pt_an,                  PT_QN pt_qn,          // buffer for queen                  BYTE  by_row_num,                   BYTE* pby_cur_rslt_num){       T_AN  at_an_tmp[AREA_X_MAX][AREA_Y_MAX];    BYTE  aby_active_node_buf[AREA_Y_MAX];    BYTE  by_active_node_num;    BYTE  by_i;    PT_AN pt_row_start = NULL;    pt_row_start = pt_an + AREA_Y_MAX * by_row_num;    Search_Active_Node_In_Row(pt_row_start, &by_active_node_num, aby_active_node_buf);    for(by_i=0 ; by_i<by_active_node_num ; by_i++)    {        if(0 == by_row_num)        {            Set_Default_Val(pt_qn, pt_an);        }            pt_qn[by_row_num].t_pos.by_x = by_row_num;        pt_qn[by_row_num].t_pos.by_y = aby_active_node_buf[by_i];                    // find a valid result        if((AREA_X_MAX-1) == by_row_num)        {            Print_QN(*pby_cur_rslt_num, pt_qn);            (*pby_cur_rslt_num)++;        }        else // search in next row        {            Copy_AN(&at_an_tmp[0][0], pt_an);             Disable_Area_Node(&pt_qn[by_row_num], &at_an_tmp[0][0]);            Match_In_Row(&at_an_tmp[0][0], pt_qn, by_row_num+1, pby_cur_rslt_num);        }    }}// ------------------------------------// main func// ------------------------------------void main(){   T_AN at_an[AREA_X_MAX][AREA_Y_MAX];   T_QN at_qn[QN_NUM];   BYTE by_rslt_num = 0;   printf("Start...\r\n");   Set_Default_Val(at_qn, &at_an[0][0]);   Match_In_Row(&at_an[0][0],                 at_qn,                           0,                 &by_rslt_num);   printf("done...\r\n");   getchar();}


0 0
原创粉丝点击