您的位置:首页 > 其它

八皇后问题

2016-02-13 21:39 323 查看
百度百科关于八皇后问题的说明:

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于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 type
typedef unsigned char   BYTE;
typedef unsigned short  WORD;
typedef unsigned long   DWORD;

// BOOL
typedef enum
{
FALSE = 0,
TRUE
}BOOL;

// pos
typedef struct
{
BYTE by_x;
BYTE by_y;
}T_Pos, *PT_Pos;

// queen
typedef struct
{
BYTE  by_sn;          // sn
T_Pos t_pos;          // pos
}T_QN, *PT_QN;

// area node
typedef 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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: